From c77140981d254715ccf7a7bff2c8048fc4faa6fb Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 27 Nov 2025 19:39:45 +0100 Subject: [PATCH 01/19] VAR|TMP overhaul 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, 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. - 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, it will be passed to a new ZEND_DEREF opcode beforehand. This is exceptionally rare. Preliminary testing shows a 1.1% wall time improvement in Symfony Demo and roughly 0.5% in Wordpress. --- Zend/tests/list/bug73663.phpt | 2 + Zend/tests/operator_unsupported_types.phpt | 8 +- Zend/zend_closures.c | 2 +- Zend/zend_compile.c | 177 +- Zend/zend_execute.c | 32 + Zend/zend_execute.h | 2 + Zend/zend_generators.c | 4 +- Zend/zend_vm_def.h | 282 +- Zend/zend_vm_execute.h | 100089 +++++++-------- Zend/zend_vm_handlers.h | 1763 +- Zend/zend_vm_opcodes.c | 152 +- Zend/zend_vm_opcodes.h | 3 +- ext/opcache/jit/zend_jit_ir.c | 2 +- ext/opcache/tests/dump_property_hooks.phpt | 4 +- ext/opcache/tests/match/001.phpt | 8 +- ext/opcache/tests/match/003.phpt | 8 +- ext/opcache/tests/match/004.phpt | 8 +- ext/opcache/tests/named_parameter_new.phpt | 8 +- ext/opcache/tests/nodiscard_001.phpt | 20 +- ext/opcache/tests/opt/block_pass_007.phpt | 4 +- ext/opcache/tests/opt/dce_006.phpt | 4 +- ext/opcache/tests/opt/gh11170.phpt | 8 +- ext/opcache/tests/opt/gh18107_1.phpt | 8 +- ext/opcache/tests/opt/gh18107_2.phpt | 8 +- ext/opcache/tests/opt/jmp_001.phpt | 4 +- ext/opcache/tests/opt/sccp_022.phpt | 12 +- ext/opcache/tests/opt/sccp_032.phpt | 16 +- .../tests/opt/type_inference_final_class.phpt | 4 +- ext/opcache/tests/pipe_optimizations.phpt | 27 +- sapi/phpdbg/tests/print_001.phpt | 4 +- sapi/phpdbg/tests/watch_005.phpt | 4 +- 31 files changed, 48213 insertions(+), 54464 deletions(-) diff --git a/Zend/tests/list/bug73663.phpt b/Zend/tests/list/bug73663.phpt index 85b61b0f46713..2dd98f3251ec0 100644 --- a/Zend/tests/list/bug73663.phpt +++ b/Zend/tests/list/bug73663.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #73663 ("Invalid opcode 65/16/8" occurs with a variable created with list()) +--XFAIL-- +list() assign resulting in a ref only when there's a single by-ref fetch is kinda weird. --FILE-- result); return; } @@ -2580,7 +2586,10 @@ 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(const zend_ast *ast); +static inline bool zend_is_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) { @@ -2588,7 +2597,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(expr) || zend_is_call(expr)) { + zend_compile_var(result, expr, type, false); + } else { + zend_compile_expr(result, expr); + } CG(memoize_mode) = ZEND_MEMOIZE_COMPILE; if (result->op_type == IS_VAR) { @@ -2717,7 +2730,8 @@ static inline bool zend_is_variable(const zend_ast *ast) /* {{{ */ || 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; } /* }}} */ @@ -3292,7 +3306,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; @@ -3352,6 +3366,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); @@ -3361,7 +3379,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 { @@ -3374,7 +3392,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) { + // FIXME: [&$a] = ...; currently emits ZEND_DEREF, avoidable? + zend_emit_op_tmp(result, ZEND_DEREF, expr_node, NULL); + } else { + *result = *expr_node; + } } else { zend_do_free(expr_node); } @@ -3535,14 +3558,14 @@ 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(result, var_ast, &expr_node, var_ast->attr, BP_VAR_R); 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]; @@ -3589,28 +3612,39 @@ 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)) { + znode tmp_result = *result; + zend_emit_op_tmp(result, ZEND_DEREF, &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); } /* }}} */ @@ -3798,7 +3832,7 @@ 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); + zend_compile_var(&arg_node, arg, is_globals_fetch(arg) ? BP_VAR_R : BP_VAR_FUNC_ARG, 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)) { @@ -3946,7 +3980,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; @@ -3983,8 +4017,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); } @@ -3998,8 +4033,15 @@ 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; + opline->extended_value |= ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS; } opline->lineno = lineno; zend_do_extended_fcall_end(); @@ -4020,7 +4062,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; @@ -4050,7 +4092,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); } /* }}} */ @@ -4292,7 +4334,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; @@ -4307,10 +4349,11 @@ static zend_result zend_compile_func_cufa(znode *result, zend_ast_list *args, ze && Z_TYPE_P(zend_ast_get_zval(args->child[1]->child[0])) == IS_STRING && args->child[1]->child[1]->kind == ZEND_AST_ARG_LIST) { zend_string *orig_name = zend_ast_get_str(args->child[1]->child[0]); - zend_ast_list *list = zend_ast_get_list(args->child[1]->child[1]); bool is_fully_qualified; zend_string *name = zend_resolve_function_name(orig_name, args->child[1]->child[0]->attr, &is_fully_qualified); +#if 0 + zend_ast_list *list = zend_ast_get_list(args->child[1]->child[1]); if (zend_string_equals_literal_ci(name, "array_slice") && !zend_args_contain_unpack_or_named(list) && list->children == 3 @@ -4332,20 +4375,25 @@ static zend_result zend_compile_func_cufa(znode *result, zend_ast_list *args, ze return SUCCESS; } } +#endif zend_string_release_ex(name, 0); } zend_compile_expr(&arg_node, args->child[1]); 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); - opline->extended_value = ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS; + opline->extended_value |= ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS; + if (type == BP_VAR_R || type == BP_VAR_IS) { + opline->result_type = IS_TMP_VAR; + result->op_type = IS_TMP_VAR; + } return SUCCESS; } /* }}} */ /* 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; @@ -4365,13 +4413,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; @@ -4406,7 +4458,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(); @@ -4657,10 +4709,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; } @@ -4771,7 +4819,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) { @@ -5079,9 +5127,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)) @@ -5214,7 +5262,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; } @@ -5229,7 +5277,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; } @@ -5238,7 +5286,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); } @@ -5255,7 +5303,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; @@ -5265,7 +5313,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; } @@ -5290,7 +5338,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); } } /* }}} */ @@ -5354,7 +5402,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"); @@ -5469,7 +5517,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); } /* }}} */ @@ -5490,7 +5538,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); @@ -5525,7 +5573,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); } /* }}} */ @@ -5800,7 +5848,8 @@ 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)) { + // FIXME: Shouldn't apply to nullsafe calls and pipes. + } else if (by_ref && (zend_is_variable(expr_ast) || zend_is_call(expr_ast))) { zend_assert_not_short_circuited(expr_ast); zend_compile_var(&expr_node, expr_ast, BP_VAR_W, true); } else { @@ -6190,7 +6239,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; @@ -6225,6 +6275,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); @@ -6237,11 +6291,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 { @@ -6579,7 +6633,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]; @@ -6634,7 +6688,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, false); } static void zend_compile_match(znode *result, zend_ast *ast) @@ -10831,7 +10885,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(value_ast) || zend_is_call(value_ast))) { zend_assert_not_short_circuited(value_ast); zend_compile_var(&value_node, value_ast, BP_VAR_W, true); } else { @@ -10840,7 +10894,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; @@ -10906,7 +10960,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(); @@ -11888,6 +11942,9 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */ case ZEND_AST_CAST_VOID: zend_compile_void_cast(NULL, ast); break; + case ZEND_AST_ASSIGN_REF: + zend_compile_assign_ref(NULL, ast, BP_VAR_R); + return; default: { znode result; @@ -11908,7 +11965,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; } @@ -11930,13 +11987,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); 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); @@ -12035,9 +12093,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 */); } @@ -12063,7 +12118,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; } @@ -12092,9 +12147,15 @@ 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; default: if (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET) { zend_error_noreturn(E_COMPILE_ERROR, diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index d411dcbc3b953..99a63a129ad35 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -5947,3 +5947,35 @@ 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_reference *ref = Z_REF_P(return_value); + ZVAL_COPY_VALUE(return_value, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(return_value); + } +} diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 8858f9fce96ae..89a9e79143a82 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -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 */ diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index d227795f66b0d..5e1377995a2ea 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -652,7 +652,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); + } } } } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 1b91f11662c7a..e0adcf13da39a 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -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,23 @@ 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_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(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 +2082,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 +2090,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 +2255,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 +2276,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 +2293,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 +2301,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 +2416,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 +2429,23 @@ 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_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(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 +2462,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 +2474,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 +2497,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 +2650,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 +2688,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 +2841,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 +2909,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 +2945,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 +3143,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 +3177,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 +3211,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 +3247,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 +3316,7 @@ ZEND_VM_HOT_HANDLER(127, ZEND_FE_FREE, TMPVAR, ANY) 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 +3441,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 +3476,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 +3511,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 +3571,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 +3614,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 +3769,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 +3930,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 +3983,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 +4299,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 +4428,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 +4538,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 +4679,10 @@ 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(); + + // FIXME: Don't create the ref in the first place? + zend_return_unwrap_ref(execute_data, return_value); + ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper); } @@ -4769,7 +4811,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; @@ -5627,7 +5669,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; @@ -5837,7 +5879,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; @@ -5882,7 +5924,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; @@ -6002,7 +6044,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; @@ -6216,7 +6258,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; @@ -6465,7 +6507,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; @@ -6487,7 +6529,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; @@ -6536,7 +6578,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; @@ -6674,7 +6716,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 @@ -6727,7 +6769,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; @@ -6829,7 +6871,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; @@ -6874,7 +6916,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; @@ -7168,7 +7210,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; @@ -7237,6 +7279,9 @@ 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 { + ZVAL_DEREF(value); + value_type = Z_TYPE_INFO_P(value); + zval *res = EX_VAR(opline->op2.var); zend_refcounted *gc = Z_COUNTED_P(value); @@ -7473,7 +7518,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; @@ -7517,7 +7562,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 @@ -7538,7 +7583,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; @@ -7617,7 +7662,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; @@ -7667,7 +7712,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 @@ -7745,7 +7790,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; @@ -7792,7 +7837,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; @@ -7833,7 +7878,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; @@ -8033,7 +8078,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; @@ -8402,7 +8447,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 @@ -8523,7 +8568,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); @@ -8760,7 +8805,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; @@ -8822,7 +8867,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; @@ -8896,7 +8941,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; @@ -9409,7 +9454,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; @@ -9481,7 +9526,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; @@ -9536,7 +9581,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)); @@ -9551,7 +9596,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 @@ -9612,7 +9657,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; @@ -9961,6 +10006,27 @@ ZEND_VM_HANDLER(209, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL, CONST, UNUSED|NUM, NUM ZEND_VM_NEXT_OPCODE(); } +ZEND_VM_HANDLER(211, ZEND_DEREF, VAR, UNUSED) +{ + USE_OPLINE + + zval *value = GET_OP1_ZVAL_PTR(BP_VAR_R); + + if (Z_TYPE_P(value) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(value); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(EX_VAR(opline->result.var)); + } + } else { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + } + + ZEND_VM_NEXT_OPCODE(); +} + ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_JMP, (OP_JMP_ADDR(op, op->op1) > op), ZEND_JMP_FORWARD, JMP_ADDR, ANY) { USE_OPLINE diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 801bf0ee69e0d..cf166987408bc 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -854,7 +854,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_STATI 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_STATIC_PROP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -882,7 +882,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_STAT 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) */ static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_fetch_static_prop_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_EX int type) { USE_OPLINE @@ -917,25 +917,25 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_fetch_static_prop_helper_ 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_STATIC_PROP_R_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_STATIC_PROP_W_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_STATIC_PROP_RW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { @@ -945,13 +945,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_STATIC_ } } -/* 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_STATIC_PROP_UNSET_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_STATIC_PROP_IS_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS)); @@ -1057,43 +1057,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_STATIC ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *prop, *value; - zend_property_info *prop_info; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - - prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(!prop)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } else { - value = zend_assign_to_variable_ex(prop, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - - /* assign_static_prop has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -1679,6 +1642,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_D ? 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 @@ -1792,6 +1756,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_D ? 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 @@ -1904,6 +1869,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ ? 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); @@ -2035,6 +2001,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_D ? 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 @@ -2165,6 +2132,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_D ? 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 @@ -2292,6 +2260,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ ? 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); @@ -4255,27 +4224,27 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_R ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_DYNAMIC_CALL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; zend_execute_data *call; SAVE_OPLINE(); - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); try_function_name: - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { call = zend_init_dynamic_call_string(Z_STR_P(function_name), opline->extended_value); - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT)) { + } else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT)) { call = zend_init_dynamic_call_object(Z_OBJ_P(function_name), opline->extended_value); } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY)) { call = zend_init_dynamic_call_array(Z_ARRVAL_P(function_name), opline->extended_value); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(function_name) == IS_REFERENCE)) { + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(function_name) == IS_REFERENCE)) { function_name = Z_REFVAL_P(function_name); goto try_function_name; } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { function_name = ZVAL_UNDEFINED_OP2(); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -4286,7 +4255,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_DYNAMIC_ call = NULL; } - if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) { + if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (UNEXPECTED(EG(exception))) { if (call) { @@ -4943,6 +4912,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ + // FIXME: Don't create the ref in the first place? + zend_return_unwrap_ref(execute_data, return_value); + ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } @@ -5009,6 +4981,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ zend_observer_fcall_end(execute_data, return_value); if (return_value == &observer_retval) { zval_ptr_dtor_nogc(&observer_retval); }; + + // FIXME: Don't create the ref in the first place? + zend_return_unwrap_ref(execute_data, return_value); + ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } @@ -6780,13 +6756,17 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); + if (IS_CONST & (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 = RT_CONSTANT(opline, opline->op2); if (IS_CONST != IS_CONST) { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_array: value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, 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 (IS_CONST == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { goto fetch_dim_r_array; @@ -6817,6 +6797,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); + /* 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, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); @@ -6840,6 +6822,18 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ if (IS_CONST == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + if (IS_CONST & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -6852,11 +6846,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); + if (IS_CONST & (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 (IS_CONST == IS_CONST || (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { do { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + if ((IS_CONST & IS_CV) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; @@ -7024,6 +7022,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ if (IS_CONST == IS_CONST || (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -7152,6 +7152,18 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ } ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { + if (IS_CONST == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -9371,14 +9383,14 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_F ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; SAVE_OPLINE(); op1 = RT_CONSTANT(opline, opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); div_function(EX_VAR(opline->result.var), op1, op2); @@ -9386,14 +9398,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_CONS ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; SAVE_OPLINE(); op1 = RT_CONSTANT(opline, opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); pow_function(EX_VAR(opline->result.var), op1, op2); @@ -9401,23 +9413,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_CONS ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; op1 = RT_CONSTANT(opline, opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { zend_string *op1_str = Z_STR_P(op1); zend_string *op2_str = Z_STR_P(op2); zend_string *str; uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); } else { ZVAL_STR(EX_VAR(opline->result.var), op2_str); @@ -9425,13 +9437,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_C if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op1_str, 0); } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + } else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } else if (IS_CONST != IS_CONST && IS_CONST != IS_CV && @@ -9445,7 +9457,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_C memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); GC_ADD_FLAGS(str, flags); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } else { @@ -9457,7 +9469,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_C if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op1_str, 0); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } @@ -9468,7 +9480,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_C if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = ZVAL_UNDEFINED_OP1(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = ZVAL_UNDEFINED_OP2(); } concat_function(EX_VAR(opline->result.var), op1, op2); @@ -9479,14 +9491,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_C } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; SAVE_OPLINE(); op1 = RT_CONSTANT(opline, opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); compare_function(EX_VAR(opline->result.var), op1, op2); @@ -9494,20 +9506,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPE ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container, *dim, *value; SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_CONST & (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_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if (IS_CONST != IS_CONST) { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R EXECUTE_DATA_CC); + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_TMP_VAR, 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 (IS_CONST == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { goto fetch_dim_r_array; @@ -9516,13 +9532,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_S } } else { fetch_dim_r_slow: - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); } } else { - zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_dimension_address_read_R(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); } zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -9530,21 +9546,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_S ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); - zend_fetch_dimension_address_read_IS(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); + /* 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_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 USE_OPLINE @@ -9556,14 +9574,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN } ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_TMP_VAR == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_CONST & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -9571,11 +9601,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); + if (IS_CONST & (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 (IS_CONST == IS_CONST || (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { do { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + if ((IS_CONST & IS_CV) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; @@ -9584,7 +9618,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - zend_wrong_property_read(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + zend_wrong_property_read(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); ZVAL_NULL(EX_VAR(opline->result.var)); goto fetch_obj_r_finish; } while (0); @@ -9596,7 +9630,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ zend_string *name, *tmp_name; zval *retval; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { @@ -9656,7 +9690,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ /* Fall through to read_property for hooks. */ } else if (EXPECTED(zobj->properties != NULL)) { ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); @@ -9689,9 +9723,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ } } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); break; @@ -9715,7 +9749,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ } #endif - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -9734,7 +9768,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -9742,6 +9776,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ if (IS_CONST == IS_CONST || (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -9752,7 +9788,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ break; } } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { + if (IS_TMP_VAR == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); } ZVAL_NULL(EX_VAR(opline->result.var)); @@ -9766,7 +9802,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ zend_string *name, *tmp_name; zval *retval; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { @@ -9793,7 +9829,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ /* Fall through to read_property for hooks. */ } else if (EXPECTED(zobj->properties != NULL)) { ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); @@ -9826,9 +9862,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ } } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); break; @@ -9837,7 +9873,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -9856,7 +9892,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 USE_OPLINE @@ -9869,23 +9905,35 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ } ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_CONST == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); - zend_fetch_dimension_address_LIST_r(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_dimension_address_LIST_r(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; @@ -9893,16 +9941,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_S op1 = RT_CONSTANT(opline, opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { zend_string *op1_str = Z_STR_P(op1); zend_string *op2_str = Z_STR_P(op2); zend_string *str; uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); } else { ZVAL_STR(EX_VAR(opline->result.var), op2_str); @@ -9910,13 +9958,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_S if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op1_str, 0); } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + } else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } else if (IS_CONST != IS_CONST && IS_CONST != IS_CV && @@ -9927,7 +9975,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_S memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); GC_ADD_FLAGS(str, flags); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } else { @@ -9939,7 +9987,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_S if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op1_str, 0); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } @@ -9957,12 +10005,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_S } op1_str = zval_get_string_func(op1); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { op2_str = Z_STR_P(op2); } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { op2_str = zend_string_copy(Z_STR_P(op2)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); } op2_str = zval_get_string_func(op2); @@ -9970,7 +10018,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_S do { if (IS_CONST != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { GC_ADDREF(op2_str); } @@ -9980,7 +10028,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_S break; } } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { if (IS_CONST == IS_CONST) { if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { @@ -10001,7 +10049,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_S if (IS_CONST != IS_CONST) { zend_string_release_ex(op1_str, 0); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_string_release_ex(op2_str, 0); } } while (0); @@ -10011,7 +10059,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_S ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; @@ -10026,19 +10074,19 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ object = RT_CONSTANT(opline, opline->op1); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR != IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && + if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); if (UNEXPECTED(EG(exception) != NULL)) { @@ -10080,14 +10128,14 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { object = ZVAL_UNDEFINED_OP1(); if (UNEXPECTED(EG(exception) != NULL)) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } HANDLE_EXCEPTION(); } } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); } zend_invalid_method_call(object, function_name); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -10100,18 +10148,18 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ called_scope = obj->ce; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_TMP_VAR == IS_CONST && EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); } /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); @@ -10122,7 +10170,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ } HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_TMP_VAR == IS_CONST && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); @@ -10138,7 +10186,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ } } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } @@ -10169,7 +10217,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; @@ -10189,7 +10237,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { CACHE_PTR(opline->result.num, ce); } } @@ -10204,24 +10252,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M } if (IS_CONST == IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && + IS_TMP_VAR == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_CONST != IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && + IS_TMP_VAR == IS_CONST && EXPECTED(CACHED_PTR(opline->result.num) == ce)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + } else if (IS_TMP_VAR != IS_UNUSED) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR != IS_CONST) { if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + if (IS_TMP_VAR & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -10237,7 +10285,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { @@ -10246,7 +10294,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_TMP_VAR == IS_CONST && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); @@ -10254,7 +10302,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } } else { @@ -10302,7 +10350,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_USER_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; @@ -10314,7 +10362,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_USER_CAL uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; SAVE_OPLINE(); - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { ZEND_ASSERT(!error); @@ -10322,7 +10370,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_USER_CAL * invoke a user error handler and throw an exception. * For the CONST and CV case we reuse the same exception block below * to make sure we don't increase VM size too much. */ - if (!((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { + if (!(IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } @@ -10347,7 +10395,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_USER_CAL } zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { + if ((IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { if (call_info & ZEND_CALL_CLOSURE) { zend_object_release(ZEND_CLOSURE_OBJECT(func)); } else if (call_info & ZEND_CALL_RELEASE_THIS) { @@ -10374,7 +10422,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_USER_CAL ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *expr_ptr, new_expr; @@ -10415,15 +10463,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELE } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR != IS_UNUSED) { + zval *offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); zend_string *str; zend_ulong hval; add_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { if (ZEND_HANDLE_NUMERIC(str, hval)) { goto num_index; } @@ -10434,7 +10482,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELE hval = Z_LVAL_P(offset); num_index: zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { offset = Z_REFVAL_P(offset); goto add_again; } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { @@ -10467,7 +10515,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELE zend_use_resource_as_offset(offset); hval = Z_RES_HANDLE_P(offset); goto num_index; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + } else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); str = ZSTR_EMPTY_ALLOC(); goto str_index; @@ -10485,7 +10533,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELE ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *array; uint32_t size; @@ -10500,14 +10548,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SP if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init_mixed(Z_ARRVAL_P(array)); } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { ZVAL_ARR(array, zend_new_array(0)); ZEND_VM_NEXT_OPCODE(); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -10517,7 +10565,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht; @@ -10529,17 +10577,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY isset_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { if (ZEND_HANDLE_NUMERIC(str, hval)) { goto num_index_prop; } } - value = zend_hash_find_ex(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST); + value = zend_hash_find_ex(ht, str, IS_TMP_VAR == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: value = zend_hash_index_find(ht, hval); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { offset = Z_REFVAL_P(offset); goto isset_again; } else { @@ -10571,7 +10619,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY } } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { offset++; } if (!(opline->extended_value & ZEND_ISEMPTY)) { @@ -10587,7 +10635,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -10597,7 +10645,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if (IS_CONST == IS_CONST || (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -10613,7 +10661,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ } } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(offset); } else { name = zval_try_get_tmp_string(offset, &tmp_name); @@ -10625,9 +10673,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ result = (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -10638,7 +10686,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -10649,14 +10697,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXI SAVE_OPLINE(); key = RT_CONSTANT(opline, opline->op1); - subject = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + subject = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { array_key_exists_array: ht = Z_ARRVAL_P(subject); result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); } else { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { subject = Z_REFVAL_P(subject); if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { goto array_key_exists_array; @@ -10672,7 +10720,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXI ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -10759,9 +10807,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CO } /* Set the new yielded key */ - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *key = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + if (IS_TMP_VAR != IS_UNUSED) { + zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { key = Z_REFVAL_P(key); } ZVAL_COPY(&generator->key, key); @@ -10930,7 +10978,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_IS_SPEC ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 @@ -10946,6 +10994,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if (IS_UNUSED == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + if (IS_CONST & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -11502,7 +11562,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_VAR_SPE 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -11547,7 +11607,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -12067,13 +12127,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_S SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); + if (IS_CONST & (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 = EX_VAR(opline->op2.var); if (IS_CONST != IS_CONST) { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_array: value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, 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 (IS_CONST == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { goto fetch_dim_r_array; @@ -12104,6 +12168,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_ SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); + /* 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, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); @@ -12127,6 +12193,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if (IS_CV == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + if (IS_CONST & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -12139,11 +12217,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); + if (IS_CONST & (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 (IS_CONST == IS_CONST || (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { do { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + if ((IS_CONST & IS_CV) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; @@ -12311,6 +12393,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ if (IS_CONST == IS_CONST || (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -12439,6 +12523,18 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ } ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { + if (IS_CONST == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -15437,14 +15533,14 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_I ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_LIST_r(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_dimension_address_LIST_r(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -15473,200 +15569,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_R_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val; - - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - /* The result and op1 can be the same cv zval */ - const uint32_t orig_val_type = Z_TYPE_INFO_P(val); - ZVAL_TRUE(EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - } else { - SAVE_OPLINE(); - ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ECHO_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *z; - - SAVE_OPLINE(); - z = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (Z_TYPE_P(z) == IS_STRING) { - zend_string *str = Z_STR_P(z); - - if (ZSTR_LEN(str) != 0) { - zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); - } - } else { - zend_string *str = zval_get_string_func(z); - - if (ZSTR_LEN(str) != 0) { - zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_string_release_ex(str, 0); - } - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val; - uint8_t op1_type; - - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - - SAVE_OPLINE(); - op1_type = (IS_TMP_VAR|IS_VAR); - if (i_zend_is_true(val)) { - opline++; - } else { - opline = OP_JMP_ADDR(opline, opline->op2); - } - if (op1_type & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_nogc(val); - } - ZEND_VM_JMP(opline); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val; - uint8_t op1_type; - - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - op1_type = (IS_TMP_VAR|IS_VAR); - if (i_zend_is_true(val)) { - opline = OP_JMP_ADDR(opline, opline->op2); - } else { - opline++; - } - if (op1_type & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_nogc(val); - } - ZEND_VM_JMP(opline); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val; - bool ret; - - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - - SAVE_OPLINE(); - ret = i_zend_is_true(val); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - if (ret) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - opline++; - } else { - ZVAL_FALSE(EX_VAR(opline->result.var)); - opline = OP_JMP_ADDR(opline, opline->op2); - } - ZEND_VM_JMP(opline); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val; - bool ret; - - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } - - SAVE_OPLINE(); - ret = i_zend_is_true(val); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - if (ret) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - opline = OP_JMP_ADDR(opline, opline->op2); - } else { - ZVAL_FALSE(EX_VAR(opline->result.var)); - opline++; - } - ZEND_VM_JMP(opline); -} - static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -15701,979 +15603,943 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_F ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_THROW_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; + zval *container, *dim, *value; SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - do { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - value = Z_REFVAL_P(value); - if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { - break; - } + container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) & (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 = RT_CONSTANT(opline, opline->op2); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R EXECUTE_DATA_CC); + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } + } else { +fetch_dim_r_slow: + if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; } - zend_throw_error(NULL, "Can only throw objects"); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); } - } while (0); + } else { + zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); + } + - zend_exception_save(); - Z_TRY_ADDREF_P(value); - zend_throw_exception_object(value); - zend_exception_restore(); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; + zval *container; - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - /* The result and op1 can be the same cv zval */ - const uint32_t orig_val_type = Z_TYPE_INFO_P(val); - ZVAL_FALSE(EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - } else { - SAVE_OPLINE(); - ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + /* 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, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *obj; - zend_object *zobj; - zend_class_entry *ce, *scope; - zend_function *clone; - zend_object_clone_obj_t clone_call; + zval *container; + void **cache_slot = NULL; SAVE_OPLINE(); - obj = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. - * The OPcode intentionally does not support a clone-with property list to keep it simple. */ + container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) & (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); + } - do { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) { - obj = Z_REFVAL_P(obj); - if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || + ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if (((IS_TMP_VAR|IS_VAR) & IS_CV) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; } } - ZVAL_UNDEF(EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } } - zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } while (0); - - zobj = Z_OBJ_P(obj); - ce = zobj->ce; - clone = ce->clone; - clone_call = zobj->handlers->clone_obj; - if (UNEXPECTED(clone_call == NULL)) { - zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); + zend_wrong_property_read(container, RT_CONSTANT(opline, opline->op2)); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; + } while (0); } - if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) { - scope = EX(func)->op_array.scope; - ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC)); - if (!zend_check_method_accessible(clone, scope)) { - zend_bad_method_call(clone, clone->common.function_name, scope); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; - ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj)); + if (IS_CONST == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_op_array *new_op_array; - zval *inc_filename; + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_r_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { +fetch_obj_r_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + prop_offset = prop_info->offset; + goto fetch_obj_r_simple; + } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { + zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; + ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); + ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); - SAVE_OPLINE(); - inc_filename = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - new_op_array = zend_include_or_eval(inc_filename, opline->extended_value); - if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) { - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); - } - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else if (new_op_array == ZEND_FAKE_OP_ARRAY) { - if (RETURN_VALUE_USED(opline)) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - } - } else if (UNEXPECTED(new_op_array == NULL)) { - if (RETURN_VALUE_USED(opline)) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - } - } else if (new_op_array->last == 1 - && new_op_array->opcodes[0].opcode == ZEND_RETURN - && new_op_array->opcodes[0].op1_type == IS_CONST - && EXPECTED(zend_execute_ex == execute_ex)) { - if (RETURN_VALUE_USED(opline)) { - const zend_op *op = new_op_array->opcodes; + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if ((IS_TMP_VAR|IS_VAR) & IS_CV) { + GC_ADDREF(zobj); + } + if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR|IS_TMP_VAR)) { + call_info |= ZEND_CALL_RELEASE_THIS; + } + zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); + call->prev_execute_data = execute_data; + call->call = NULL; + call->return_value = EX_VAR(opline->result.var); + call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); - ZVAL_COPY(EX_VAR(opline->result.var), RT_CONSTANT(op, op->op1)); - } - zend_destroy_static_vars(new_op_array); - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); - } else { - zval *return_value = NULL; - zend_execute_data *call; - if (RETURN_VALUE_USED(opline)) { - return_value = EX_VAR(opline->result.var); - } + execute_data = call; + EG(current_execute_data) = execute_data; + zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); - new_op_array->scope = EX(func)->op_array.scope; +#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) + opline = hook->op_array.opcodes; +#else + EX(opline) = hook->op_array.opcodes; +#endif + LOAD_OPLINE_EX(); - call = zend_vm_stack_push_call_frame( - (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, - (zend_function*)new_op_array, 0, - Z_PTR(EX(This))); - if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { - call->symbol_table = EX(symbol_table); - } else { - call->symbol_table = zend_rebuild_symbol_table(); - } - call->prev_execute_data = execute_data; - i_init_code_execute_data(call, new_op_array, return_value); + ZEND_VM_ENTER_EX(); + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); - if (EXPECTED(zend_execute_ex == execute_ex)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_ENTER(); + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } + } + } + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); } else { - ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); - zend_execute_ex(call); - zend_vm_stack_free_call_frame(call); + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; + } } - zend_destroy_static_vars(new_op_array); - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); +#if ZEND_DEBUG + /* For non-standard object handlers, verify a declared property type in debug builds. + * Fetch prop_info before calling read_property(), as it may deallocate the object. */ + zend_property_info *prop_info = NULL; + if (zobj->handlers->read_property != zend_std_read_property) { + prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); } - } +#endif + retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO + && ZEND_TYPE_IS_SET(prop_info->type)) { + ZVAL_OPT_DEREF(retval); + zend_verify_property_type(prop_info, retval, /* strict */ true); + } +#endif + + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_r_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } + } while (0); + +fetch_obj_r_finish: + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_FROM_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - zval *val; + zval *container; + void **cache_slot = NULL; SAVE_OPLINE(); - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator"); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || + ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + if (IS_CONST == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + } + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; + } while (0); } -yield_from_try_again: - if (Z_TYPE_P(val) == IS_ARRAY) { - ZVAL_COPY_VALUE(&generator->values, val); - if (Z_OPT_REFCOUNTED_P(val)) { - Z_ADDREF_P(val); - } - Z_FE_POS(generator->values) = 0; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) { - zend_class_entry *ce = Z_OBJCE_P(val); - if (ce == zend_ce_generator) { - zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; - Z_ADDREF_P(val); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (IS_CONST == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value); - if (UNEXPECTED(new_gen->execute_data == NULL)) { - zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); - zval_ptr_dtor(val); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else if (Z_ISUNDEF(new_gen->retval)) { - if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) { - zend_throw_error(NULL, "Impossible to yield from the Generator being currently run"); - zval_ptr_dtor(val); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else { - zend_generator_yield_from(generator, new_gen); - } - } else { - if (RETURN_VALUE_USED(opline)) { - ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval); + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_is_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { +fetch_obj_is_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + goto fetch_obj_is_simple; + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } + } } - ZEND_VM_NEXT_OPCODE(); } + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); } else { - zend_object_iterator *iter = ce->get_iterator(ce, val, 0); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) { - if (!EG(exception)) { - zend_throw_error(NULL, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name)); - } - UNDEF_RESULT(); - HANDLE_EXCEPTION(); + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; } + } - iter->index = 0; - if (iter->funcs->rewind) { - iter->funcs->rewind(iter); - if (UNEXPECTED(EG(exception) != NULL)) { - OBJ_RELEASE(&iter->std); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - } + retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - ZVAL_OBJ(&generator->values, &iter->std); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(val) == IS_REFERENCE) { - val = Z_REFVAL_P(val); - goto yield_from_try_again; - } else { - zend_throw_error(NULL, "Can use \"yield from\" only with arrays and Traversables"); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - /* This is the default return value - * when the expression is a Generator, it will be overwritten in zend_generator_resume() */ - if (RETURN_VALUE_USED(opline)) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_is_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } + } while (0); - /* This generator has no send target (though the generator we delegate to might have one) */ - generator->send_target = NULL; +fetch_obj_is_finish: - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); - ZEND_VM_RETURN(); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_STRLEN_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(value); - } - ZEND_VM_NEXT_OPCODE(); - } else { - bool strict; - - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) { - value = Z_REFVAL_P(value); - if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); - } - } + zval *value, *arg; + if (IS_CONST == IS_CONST) { SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - value = ZVAL_UNDEFINED_OP1(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + uint32_t arg_num; + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); } - strict = EX_USES_STRICT_TYPES(); - do { - if (EXPECTED(!strict)) { - zend_string *str; - zval tmp; - - if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) { - zend_error(E_DEPRECATED, - "strlen(): Passing null to parameter #1 ($string) of type string is deprecated"); - ZVAL_LONG(EX_VAR(opline->result.var), 0); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - break; - } + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + } - ZVAL_COPY(&tmp, value); - if (zend_parse_arg_str_weak(&tmp, &str, 1)) { - ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str)); - zval_ptr_dtor(&tmp); - break; - } - zval_ptr_dtor(&tmp); - } - if (!EG(exception)) { - zend_type_error("strlen(): Argument #1 ($string) must be of type string, %s given", zend_zval_value_name(value)); - } - ZVAL_UNDEF(EX_VAR(opline->result.var)); - } while (0); + value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(arg, value); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { + Z_ADDREF_P(arg); + } } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_TYPE_CHECK_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - int result = 0; + zval *container, *dim, *value; + zend_long offset; + HashTable *ht; - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { -type_check_resource: - if (opline->extended_value != MAY_BE_RESOURCE - || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) { - result = 1; + container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + dim = RT_CONSTANT(opline, opline->op2); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - } else if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) { - value = Z_REFVAL_P(value); - if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { - goto type_check_resource; + ht = Z_ARRVAL_P(container); + ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - result = ((1 << IS_NULL) & opline->extended_value) != 0; - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; } - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + } else { +fetch_dim_r_index_slow: SAVE_OPLINE(); + if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); - } else { - ZEND_VM_SMART_BRANCH(result, 0); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_undefined_offset(offset); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - uint32_t fetch_type; - zend_class_entry *called_scope, *scope; USE_OPLINE + zval *container, *dim, *value; + zend_long offset; + HashTable *ht; - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + dim = EX_VAR(opline->op2.var); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + ht = Z_ARRVAL_P(container); + ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; + } + } else { +fetch_dim_r_index_slow: SAVE_OPLINE(); - zval *op = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(Z_TYPE_P(op) != IS_OBJECT)) { - ZVAL_DEREF(op); - if (Z_TYPE_P(op) != IS_OBJECT) { - zend_type_error("Cannot use \"::class\" on %s", zend_zval_value_name(op)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } + if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; } - - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op)->name); + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - fetch_type = opline->op1.num; - scope = EX(func)->op_array.scope; - if (UNEXPECTED(scope == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", - fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : - fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - - switch (fetch_type) { - case ZEND_FETCH_CLASS_SELF: - ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->name); - break; - case ZEND_FETCH_CLASS_PARENT: - if (UNEXPECTED(scope->parent == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, - "Cannot use \"parent\" when current class scope has no parent"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->parent->name); - break; - case ZEND_FETCH_CLASS_STATIC: - if (Z_TYPE(EX(This)) == IS_OBJECT) { - called_scope = Z_OBJCE(EX(This)); - } else { - called_scope = Z_CE(EX(This)); - } - ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - ZEND_VM_NEXT_OPCODE(); +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_undefined_offset(offset); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *container, *dim, *value; SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - div_function(EX_VAR(opline->result.var), op1, op2); + container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) & (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_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_TMP_VAR, BP_VAR_R EXECUTE_DATA_CC); + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; + } + } else { +fetch_dim_r_slow: + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); + } + } else { + zend_fetch_dimension_address_read_R(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *container; SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - pow_function(EX_VAR(opline->result.var), op1, op2); + container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + /* 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_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); + zval *container; + void **cache_slot = NULL; - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) & (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 ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || + ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if (((IS_TMP_VAR|IS_VAR) & IS_CV) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); + zend_wrong_property_read(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; + } while (0); + } - if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { - zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); - } - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; + + if (IS_TMP_VAR == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); + + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_r_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { +fetch_obj_r_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + prop_offset = prop_info->offset; + goto fetch_obj_r_simple; + } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { + zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; + ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); + ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); + + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if ((IS_TMP_VAR|IS_VAR) & IS_CV) { + GC_ADDREF(zobj); + } + if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR|IS_TMP_VAR)) { + call_info |= ZEND_CALL_RELEASE_THIS; + } + zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); + call->prev_execute_data = execute_data; + call->call = NULL; + call->return_value = EX_VAR(opline->result.var); + call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); + + execute_data = call; + EG(current_execute_data) = execute_data; + zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); + +#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) + opline = hook->op_array.opcodes; +#else + EX(opline) = hook->op_array.opcodes; +#endif + LOAD_OPLINE_EX(); + + + + + ZEND_VM_ENTER_EX(); + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } + } } + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; } } - ZEND_VM_NEXT_OPCODE(); - } else { - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = ZVAL_UNDEFINED_OP1(); +#if ZEND_DEBUG + /* For non-standard object handlers, verify a declared property type in debug builds. + * Fetch prop_info before calling read_property(), as it may deallocate the object. */ + zend_property_info *prop_info = NULL; + if (zobj->handlers->read_property != zend_std_read_property) { + prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = ZVAL_UNDEFINED_OP2(); +#endif + retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO + && ZEND_TYPE_IS_SET(prop_info->type)) { + ZVAL_OPT_DEREF(retval); + zend_verify_property_type(prop_info, retval, /* strict */ true); } - concat_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); +#endif + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_r_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } + } while (0); + +fetch_obj_r_finish: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *container; + void **cache_slot = NULL; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || + ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; + if (IS_TMP_VAR == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; + } while (0); + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} + if (IS_TMP_VAR == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_is_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { +fetch_obj_is_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + goto fetch_obj_is_simple; + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } + } + } } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + } else { + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; } } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; + retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } + + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_is_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + } while (0); + +fetch_obj_is_finish: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *value, *arg; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; + if (IS_UNUSED == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + uint32_t arg_num; + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + } + + value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(arg, value); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { + Z_ADDREF_P(arg); } } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *varname; + zend_string *name, *tmp_name; + HashTable *target_symbol_table; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; + SAVE_OPLINE(); + + varname = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = ZVAL_UNDEFINED_OP1(); } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } + name = zval_try_get_tmp_string(varname, &tmp_name); + if (UNEXPECTED(!name)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); } } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; + target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); + zend_hash_del_ind(target_symbol_table, name); - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - compare_function(EX_VAR(opline->result.var), op1, op2); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); + } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - boolean_xor_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zval *result = EX_VAR(opline->result.var); + ZVAL_COPY(result, value); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container, *dim, *value; SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - dim = RT_CONSTANT(opline, opline->op2); + if ((IS_TMP_VAR|IS_VAR) & (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 = EX_VAR(opline->op2.var); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R EXECUTE_DATA_CC); + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, 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 ((IS_TMP_VAR|IS_VAR) == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { goto fetch_dim_r_array; @@ -16682,13 +16548,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_S } } else { fetch_dim_r_slow: - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); } } else { - zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_dimension_address_read_R(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC); } @@ -16696,21 +16562,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_S ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_IS(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); + /* 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, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -16718,11 +16586,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_S SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) & (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 ((IS_TMP_VAR|IS_VAR) == IS_CONST || ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + if (((IS_TMP_VAR|IS_VAR) & IS_CV) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; @@ -16731,7 +16603,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_S if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - zend_wrong_property_read(container, RT_CONSTANT(opline, opline->op2)); + zend_wrong_property_read(container, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); ZVAL_NULL(EX_VAR(opline->result.var)); goto fetch_obj_r_finish; } while (0); @@ -16743,7 +16615,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_S zend_string *name, *tmp_name; zval *retval; - if (IS_CONST == IS_CONST) { + if (IS_CV == IS_CONST) { cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { @@ -16803,7 +16675,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_S /* Fall through to read_property for hooks. */ } else if (EXPECTED(zobj->properties != NULL)) { ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); @@ -16836,9 +16708,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_S } } } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); break; @@ -16862,7 +16734,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_S } #endif - if (IS_CONST != IS_CONST) { + if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -16881,7 +16753,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_S ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -16889,6 +16761,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_ SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ if ((IS_TMP_VAR|IS_VAR) == IS_CONST || ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -16899,7 +16773,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_ break; } } - if (IS_CONST == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { + if (IS_CV == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); } ZVAL_NULL(EX_VAR(opline->result.var)); @@ -16913,7 +16787,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_ zend_string *name, *tmp_name; zval *retval; - if (IS_CONST == IS_CONST) { + if (IS_CV == IS_CONST) { cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { @@ -16940,7 +16814,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_ /* Fall through to read_property for hooks. */ } else if (EXPECTED(zobj->properties != NULL)) { ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); @@ -16973,9 +16847,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_ } } } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); break; @@ -16984,7 +16858,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_ retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - if (IS_CONST != IS_CONST) { + if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -17003,1555 +16877,1463 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_NOT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - zend_string *op1_str, *op2_str, *str; - - - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); + zval *val; - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + /* The result and op1 can be the same cv zval */ + const uint32_t orig_val_type = Z_TYPE_INFO_P(val); + ZVAL_TRUE(EX_VAR(opline->result.var)); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ECHO_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *z; SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - op1_str = Z_STR_P(op1); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - op1_str = zend_string_copy(Z_STR_P(op1)); - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + z = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + if (Z_TYPE_P(z) == IS_STRING) { + zend_string *str = Z_STR_P(z); + + if (ZSTR_LEN(str) != 0) { + zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); } - op1_str = zval_get_string_func(op1); - } - if (IS_CONST == IS_CONST) { - op2_str = Z_STR_P(op2); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - op2_str = zend_string_copy(Z_STR_P(op2)); } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); + zend_string *str = zval_get_string_func(z); + + if (ZSTR_LEN(str) != 0) { + zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } - op2_str = zval_get_string_func(op2); + zend_string_release_ex(str, 0); } - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { - GC_ADDREF(op2_str); - } - } - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - zend_string_release_ex(op1_str, 0); - break; - } - } - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { - GC_ADDREF(op1_str); - } - } - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - zend_string_release_ex(op2_str, 0); - break; - } - } - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CONST != IS_CONST) { - zend_string_release_ex(op2_str, 0); - } - } while (0); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zval *object; - zend_function *fbc; - zend_class_entry *called_scope; - zend_object *obj; - zend_execute_data *call; - uint32_t call_info; - - SAVE_OPLINE(); - - object = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zval *val; + uint8_t op1_type; - if (IS_CONST != IS_CONST) { - function_name = RT_CONSTANT(opline, opline->op2); - } + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if (IS_CONST != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); } - zend_throw_error(NULL, "Method name must be a string"); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } while (0); + } + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - obj = Z_OBJ_P(object); + SAVE_OPLINE(); + op1_type = IS_TMP_VAR; + if (i_zend_is_true(val)) { + opline++; } else { - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - } else { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - zend_reference *ref = Z_REF_P(object); - - object = &ref->val; - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) & IS_VAR) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_ADDREF_P(object); - } - } - break; - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - object = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CONST != IS_CONST) { - + opline = OP_JMP_ADDR(opline, opline->op2); + } + if (op1_type & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_nogc(val); + } + ZEND_VM_JMP(opline); +} - } - HANDLE_EXCEPTION(); - } - } - if (IS_CONST == IS_CONST) { - function_name = RT_CONSTANT(opline, opline->op2); - } - zend_invalid_method_call(object, function_name); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val; + uint8_t op1_type; + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } - } while (0); + } + ZEND_VM_NEXT_OPCODE(); } - called_scope = obj->ce; - - if (IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + SAVE_OPLINE(); + op1_type = IS_TMP_VAR; + if (i_zend_is_true(val)) { + opline = OP_JMP_ADDR(opline, opline->op2); } else { - zend_object *orig_obj = obj; - - if (IS_CONST == IS_CONST) { - function_name = RT_CONSTANT(opline, opline->op2); - } - - /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); - } - - - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); - } - HANDLE_EXCEPTION(); - } - if (IS_CONST == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); - } - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ - if (GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); - } - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } + opline++; } + if (op1_type & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_nogc(val); + } + ZEND_VM_JMP(opline); +} - if (IS_CONST != IS_CONST) { - +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val; + bool ret; - } + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { - zend_objects_store_del(obj); + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } } - /* call static method */ - obj = (zend_object*)called_scope; - call_info = ZEND_CALL_NESTED_FUNCTION; - } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ - } - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, obj); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + ret = i_zend_is_true(val); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (ret) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + opline++; + } else { + ZVAL_FALSE(EX_VAR(opline->result.var)); + opline = OP_JMP_ADDR(opline, opline->op2); + } + ZEND_VM_JMP(opline); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPNZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value, *arg; + zval *val; + bool ret; - if (IS_CONST == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - uint32_t arg_num; - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); } - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(arg, value); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { - Z_ADDREF_P(arg); - } + SAVE_OPLINE(); + ret = i_zend_is_true(val); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (ret) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + opline = OP_JMP_ADDR(opline, opline->op2); + } else { + ZVAL_FALSE(EX_VAR(opline->result.var)); + opline++; } - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_JMP(opline); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *retval_ptr; + zval *return_value; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -case_true: - ZEND_VM_SMART_BRANCH_TRUE(); - } else { -case_false: - ZEND_VM_SMART_BRANCH_FALSE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto case_double; + + retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + return_value = EX(return_value); + + + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) { + SAVE_OPLINE(); + retval_ptr = ZVAL_UNDEFINED_OP1(); + if (return_value) { + ZVAL_NULL(return_value); } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -case_double: - if (d1 == d2) { - goto case_true; - } else { - goto case_false; + } else if (!return_value) { + if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) { + if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) { + SAVE_OPLINE(); + rc_dtor_func(Z_COUNTED_P(retval_ptr)); } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto case_double; } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - + } else { + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { + ZVAL_COPY_VALUE(return_value, retval_ptr); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) { + Z_ADDREF_P(return_value); + } + } + } else if (IS_TMP_VAR == IS_CV) { + do { + if (Z_OPT_REFCOUNTED_P(retval_ptr)) { + if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { + if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + ZVAL_COPY_VALUE(return_value, retval_ptr); + if (GC_MAY_LEAK(ref)) { + SAVE_OPLINE(); + gc_possible_root(ref); + } + ZVAL_NULL(retval_ptr); + break; + } else { + Z_ADDREF_P(retval_ptr); + } + } else { + retval_ptr = Z_REFVAL_P(retval_ptr); + if (Z_OPT_REFCOUNTED_P(retval_ptr)) { + Z_ADDREF_P(retval_ptr); + } + } + } + ZVAL_COPY_VALUE(return_value, retval_ptr); + } while (0); + } else /* if (IS_TMP_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(retval_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); - if (result) { - goto case_true; + retval_ptr = Z_REFVAL_P(retval_ptr); + ZVAL_COPY_VALUE(return_value, retval_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { + Z_ADDREF_P(retval_ptr); + } } else { - goto case_false; + ZVAL_COPY_VALUE(return_value, retval_ptr); } } } - ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + + + + + + + ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - bool result; - zend_ulong hval; - zval *offset; + zval *retval_ptr; + zval *return_value; + SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = RT_CONSTANT(opline, opline->op2); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; - zval *value; - zend_string *str; + return_value = EX(return_value); -isset_dim_obj_array: - ht = Z_ARRVAL_P(container); -isset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_CONST != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index_prop; + + do { + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) || + (IS_TMP_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { + /* Not supposed to happen, but we'll allow it */ + zend_error(E_NOTICE, "Only variable references should be returned by reference"); + + retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (!return_value) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } else { + if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) { + ZVAL_COPY_VALUE(return_value, retval_ptr); + break; + } + + ZVAL_NEW_REF(return_value, retval_ptr); + if (IS_TMP_VAR == IS_CONST) { + Z_TRY_ADDREF_P(retval_ptr); } } - value = zend_hash_find_ex(ht, str, IS_CONST == IS_CONST); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_prop: - value = zend_hash_index_find(ht, hval); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { - offset = Z_REFVAL_P(offset); - goto isset_again; - } else { - value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); - if (UNEXPECTED(EG(exception))) { - result = 0; - goto isset_dim_obj_exit; - } + break; } - if (!(opline->extended_value & ZEND_ISEMPTY)) { - /* > IS_NULL means not IS_UNDEF and not IS_NULL */ - result = value != NULL && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - - if ((IS_TMP_VAR|IS_VAR) & (IS_CONST|IS_CV)) { - /* avoid exception check */ - + retval_ptr = zend_get_bad_ptr(); - ZEND_VM_SMART_BRANCH(result, 0); + if (IS_TMP_VAR == IS_VAR) { + ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) { + zend_error(E_NOTICE, "Only variable references should be returned by reference"); + if (return_value) { + ZVAL_NEW_REF(return_value, retval_ptr); + } else { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } + break; } - } else { - result = (value == NULL || !i_zend_is_true(value)); } - goto isset_dim_obj_exit; - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto isset_dim_obj_array; + + if (return_value) { + if (Z_ISREF_P(retval_ptr)) { + Z_ADDREF_P(retval_ptr); + } else { + ZVAL_MAKE_REF_EX(retval_ptr, 2); + } + ZVAL_REF(return_value, Z_REF_P(retval_ptr)); } - } - if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - if (!(opline->extended_value & ZEND_ISEMPTY)) { - result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); - } else { - result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); - } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } while (0); -isset_dim_obj_exit: - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + + // FIXME: Don't create the ref in the first place? + zend_return_unwrap_ref(execute_data, return_value); + + ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GENERATOR_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - int result; - zval *offset; - zend_string *name, *tmp_name; + zval *retval; - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = RT_CONSTANT(opline, opline->op2); + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; + SAVE_OPLINE(); + retval = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + /* Copy return value into generator->retval */ + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { + ZVAL_COPY_VALUE(&generator->retval, retval); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) { + Z_ADDREF(generator->retval); } - } else { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; } - } + } else if (IS_TMP_VAR == IS_CV) { + ZVAL_COPY_DEREF(&generator->retval, retval); + } else /* if (IS_TMP_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_refcounted *ref = Z_COUNTED_P(retval); - if (IS_CONST == IS_CONST) { - name = Z_STR_P(offset); - } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - result = 0; - goto isset_object_finish; + retval = Z_REFVAL_P(retval); + ZVAL_COPY_VALUE(&generator->retval, retval); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(retval)) { + Z_ADDREF_P(retval); + } + } else { + ZVAL_COPY_VALUE(&generator->retval, retval); } } - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } -isset_object_finish: + EG(current_execute_data) = EX(prev_execute_data); + /* Close the generator to free up resources */ + zend_generator_close(generator, 1); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + /* Pass execution back to handling code */ + ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - - zval *key, *subject; - HashTable *ht; - bool result; + zval *value; SAVE_OPLINE(); + value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - key = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - subject = RT_CONSTANT(opline, opline->op2); - - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { -array_key_exists_array: - ht = Z_ARRVAL_P(subject); - result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); - } else { - if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { - subject = Z_REFVAL_P(subject); - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { - goto array_key_exists_array; + do { + if (IS_TMP_VAR == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + value = Z_REFVAL_P(value); + if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { + break; + } } + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Can only throw objects"); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); } - zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); - result = 0; - } - + } while (0); + zend_exception_save(); + Z_TRY_ADDREF_P(value); + zend_throw_exception_object(value); + zend_exception_restore(); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + HANDLE_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_USER_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *expr; - bool result; + zval *arg, *param; SAVE_OPLINE(); - expr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); -try_instanceof: - if (Z_TYPE_P(expr) == IS_OBJECT) { - zend_class_entry *ce; - - if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(opline->extended_value); - if (UNEXPECTED(ce == NULL)) { - ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (EXPECTED(ce)) { - CACHE_PTR(opline->extended_value, ce); - } - } - } else if (IS_CONST == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - result = ce && instanceof_function(Z_OBJCE_P(expr), ce); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { - expr = Z_REFVAL_P(expr); - goto try_instanceof; + arg = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + param = ZEND_CALL_VAR(EX(call), opline->result.var); + if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) { + zend_param_must_be_ref(EX(call)->func, opline->op2.num); + Z_TRY_ADDREF_P(arg); + ZVAL_NEW_REF(param, arg); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - result = 0; + ZVAL_COPY(param, arg); } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container, *dim, *value; - zend_long offset; - HashTable *ht; + zval *val; - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - dim = RT_CONSTANT(opline, opline->op2); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_index_array: - if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { - offset = Z_LVAL_P(dim); - } else { - SAVE_OPLINE(); - zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - ht = Z_ARRVAL_P(container); - ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + /* The result and op1 can be the same cv zval */ + const uint32_t orig_val_type = Z_TYPE_INFO_P(val); + ZVAL_FALSE(EX_VAR(opline->result.var)); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) { SAVE_OPLINE(); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEFINED_OP1(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_index_array; - } else { - goto fetch_dim_r_index_slow; } } else { -fetch_dim_r_index_slow: SAVE_OPLINE(); - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); + ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val)); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - -fetch_dim_r_index_undef: - ZVAL_NULL(EX_VAR(opline->result.var)); - SAVE_OPLINE(); - zend_undefined_offset(offset); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container, *dim, *value; - zend_long offset; - HashTable *ht; + zval *obj; + zend_object *zobj; + zend_class_entry *ce, *scope; + zend_function *clone; + zend_object_clone_obj_t clone_call; - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - dim = EX_VAR(opline->op2.var); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_index_array: - if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { - offset = Z_LVAL_P(dim); - } else { - SAVE_OPLINE(); - zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC); + SAVE_OPLINE(); + obj = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. + * The OPcode intentionally does not support a clone-with property list to keep it simple. */ + + do { + if (IS_TMP_VAR == IS_CONST || + (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) { + obj = Z_REFVAL_P(obj); + if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) { + break; + } + } + ZVAL_UNDEF(EX_VAR(opline->result.var)); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj)); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + HANDLE_EXCEPTION(); } - ht = Z_ARRVAL_P(container); - ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - SAVE_OPLINE(); + } while (0); + + zobj = Z_OBJ_P(obj); + ce = zobj->ce; + clone = ce->clone; + clone_call = zobj->handlers->clone_obj; + if (UNEXPECTED(clone_call == NULL)) { + zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + + if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) { + scope = EX(func)->op_array.scope; + ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC)); + if (!zend_check_method_accessible(clone, scope)) { + zend_bad_method_call(clone, clone->common.function_name, scope); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_index_array; - } else { - goto fetch_dim_r_index_slow; - } - } else { -fetch_dim_r_index_slow: - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } - zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -fetch_dim_r_index_undef: - ZVAL_NULL(EX_VAR(opline->result.var)); - SAVE_OPLINE(); - zend_undefined_offset(offset); + ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *expr; + zval *result = EX_VAR(opline->result.var); SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - div_function(EX_VAR(opline->result.var), op1, op2); + expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + switch (opline->extended_value) { + case IS_LONG: + ZVAL_LONG(result, zval_get_long(expr)); + break; + case IS_DOUBLE: + ZVAL_DOUBLE(result, zval_get_double(expr)); + break; + case IS_STRING: + ZVAL_STR(result, zval_get_string(expr)); + break; + default: + ZEND_ASSERT(opline->extended_value != _IS_BOOL && "Must use ZEND_BOOL instead"); + if (IS_TMP_VAR & (IS_VAR|IS_CV)) { + ZVAL_DEREF(expr); + } + /* If value is already of correct type, return it directly */ + if (Z_TYPE_P(expr) == opline->extended_value) { + ZVAL_COPY_VALUE(result, expr); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); + } else if (IS_TMP_VAR != IS_TMP_VAR) { + if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); + } + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + + if (opline->extended_value == IS_ARRAY) { + zend_cast_zval_to_array(result, expr, IS_TMP_VAR); + } else { + ZEND_ASSERT(opline->extended_value == IS_OBJECT); + zend_cast_zval_to_object(result, expr, IS_TMP_VAR); + } + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zend_op_array *new_op_array; + zval *inc_filename; SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - pow_function(EX_VAR(opline->result.var), op1, op2); + inc_filename = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + new_op_array = zend_include_or_eval(inc_filename, opline->extended_value); + if (UNEXPECTED(EG(exception) != NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) { + destroy_op_array(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); + } + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else if (new_op_array == ZEND_FAKE_OP_ARRAY) { + if (RETURN_VALUE_USED(opline)) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + } + } else if (UNEXPECTED(new_op_array == NULL)) { + if (RETURN_VALUE_USED(opline)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + } + } else if (new_op_array->last == 1 + && new_op_array->opcodes[0].opcode == ZEND_RETURN + && new_op_array->opcodes[0].op1_type == IS_CONST + && EXPECTED(zend_execute_ex == execute_ex)) { + if (RETURN_VALUE_USED(opline)) { + const zend_op *op = new_op_array->opcodes; + + ZVAL_COPY(EX_VAR(opline->result.var), RT_CONSTANT(op, op->op1)); + } + zend_destroy_static_vars(new_op_array); + destroy_op_array(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); + } else { + zval *return_value = NULL; + zend_execute_data *call; + if (RETURN_VALUE_USED(opline)) { + return_value = EX_VAR(opline->result.var); + } + + new_op_array->scope = EX(func)->op_array.scope; + + call = zend_vm_stack_push_call_frame( + (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, + (zend_function*)new_op_array, 0, + Z_PTR(EX(This))); + + if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { + call->symbol_table = EX(symbol_table); + } else { + call->symbol_table = zend_rebuild_symbol_table(); + } + + call->prev_execute_data = execute_data; + i_init_code_execute_data(call, new_op_array, return_value); + + + if (EXPECTED(zend_execute_ex == execute_ex)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_ENTER(); + } else { + ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); + zend_execute_ex(call); + zend_vm_stack_free_call_frame(call); + } + + zend_destroy_static_vars(new_op_array); + destroy_op_array(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *array_ptr, *result; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + SAVE_OPLINE(); - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + array_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { + result = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(result, array_ptr); + if (IS_TMP_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) { + Z_ADDREF_P(array_ptr); + } + Z_FE_POS_P(result) = 0; - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); + + ZEND_VM_NEXT_OPCODE(); + } else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { + zend_object *zobj = Z_OBJ_P(array_ptr); + if (!zobj->ce->get_iterator) { + if (UNEXPECTED(zend_object_is_lazy(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (UNEXPECTED(EG(exception))) { + UNDEF_RESULT(); + + + HANDLE_EXCEPTION(); + } } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + HashTable *properties = zobj->properties; + if (properties) { + if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(properties); + } + properties = zobj->properties = zend_array_dup(properties); + } } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); + properties = zobj->handlers->get_properties(zobj); } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { - zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); + result = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(result, array_ptr); + if (IS_TMP_VAR != IS_TMP_VAR) { + Z_ADDREF_P(array_ptr); } - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); + + if (zend_hash_num_elements(properties) == 0) { + Z_FE_ITER_P(result) = (uint32_t) -1; + + + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } + + Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); + bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } else if (is_empty) { + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } else { + ZEND_VM_NEXT_OPCODE(); } } - ZEND_VM_NEXT_OPCODE(); } else { - SAVE_OPLINE(); - - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = ZVAL_UNDEFINED_OP1(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = ZVAL_UNDEFINED_OP2(); - } - concat_function(EX_VAR(opline->result.var), op1, op2); + zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *array_ptr, *array_ref; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; + SAVE_OPLINE(); + + if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { + array_ref = array_ptr = zend_get_bad_ptr(); + if (Z_ISREF_P(array_ref)) { + array_ptr = Z_REFVAL_P(array_ref); } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; + } else { + array_ref = array_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + } + + if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { + if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { + if (array_ptr == array_ref) { + ZVAL_NEW_REF(array_ref, array_ref); + array_ptr = Z_REFVAL_P(array_ref); } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; + Z_ADDREF_P(array_ref); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); + } else { + array_ref = EX_VAR(opline->result.var); + ZVAL_NEW_REF(array_ref, array_ptr); + array_ptr = Z_REFVAL_P(array_ref); } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; - } + if (IS_TMP_VAR == IS_CONST) { + ZVAL_ARR(array_ptr, zend_array_dup(Z_ARRVAL_P(array_ptr))); + } else { + SEPARATE_ARRAY(array_ptr); } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} + Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + ZEND_VM_NEXT_OPCODE(); + } else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { + if (!Z_OBJCE_P(array_ptr)->get_iterator) { + zend_object *zobj = Z_OBJ_P(array_ptr); + HashTable *properties; + if (UNEXPECTED(zend_object_is_lazy(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (UNEXPECTED(EG(exception))) { + UNDEF_RESULT(); + + + HANDLE_EXCEPTION(); + } } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; + if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { + if (array_ptr == array_ref) { + ZVAL_NEW_REF(array_ref, array_ref); + array_ptr = Z_REFVAL_P(array_ref); + } + Z_ADDREF_P(array_ref); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); } else { - goto is_equal_false; + array_ptr = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(array_ptr, array_ref); } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); + if (Z_OBJ_P(array_ptr)->properties + && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(Z_OBJ_P(array_ptr)->properties); + } + Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); + + properties = Z_OBJPROP_P(array_ptr); + if (zend_hash_num_elements(properties) == 0) { + Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1; + + + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } - if (result) { - goto is_equal_true; + + Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } else if (is_empty) { + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } else { - goto is_equal_false; + ZEND_VM_NEXT_OPCODE(); } } + } else { + zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_FETCH_R_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *array; + zval *value; + uint32_t value_type; + HashTable *fe_ht; + HashPosition pos; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + array = EX_VAR(opline->op1.var); + if (UNEXPECTED(Z_TYPE_P(array) != IS_ARRAY)) { + ZEND_VM_TAIL_CALL(zend_fe_fetch_object_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + fe_ht = Z_ARRVAL_P(array); + pos = Z_FE_POS_P(array); + if (HT_IS_PACKED(fe_ht)) { + value = fe_ht->arPacked + pos; + while (1) { + if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { + /* reached end of iteration */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; + value_type = Z_TYPE_INFO_P(value); + ZEND_ASSERT(value_type != IS_INDIRECT); + if (EXPECTED(value_type != IS_UNDEF)) { + break; } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; + pos++; + value++; } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); + Z_FE_POS_P(array) = pos + 1; + if (RETURN_VALUE_USED(opline)) { + ZVAL_LONG(EX_VAR(opline->result.var), pos); + } + } else { + Bucket *p; + + p = fe_ht->arData + pos; + while (1) { + if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { + /* reached end of iteration */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); + pos++; + value = &p->val; + value_type = Z_TYPE_INFO_P(value); + ZEND_ASSERT(value_type != IS_INDIRECT); + if (EXPECTED(value_type != IS_UNDEF)) { + break; } - if (result) { - goto is_equal_true; + p++; + } + Z_FE_POS_P(array) = pos; + if (RETURN_VALUE_USED(opline)) { + if (!p->key) { + ZVAL_LONG(EX_VAR(opline->result.var), p->h); } else { - goto is_equal_false; + ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); } } } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} + if (EXPECTED(opline->op2_type == IS_CV)) { + zval *variable_ptr = EX_VAR(opline->op2.var); + SAVE_OPLINE(); + zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZVAL_DEREF(value); + value_type = Z_TYPE_INFO_P(value); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *res = EX_VAR(opline->op2.var); + zend_refcounted *gc = Z_COUNTED_P(value); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } + ZVAL_COPY_VALUE_EX(res, value, gc, value_type); + if (Z_TYPE_INFO_REFCOUNTED(value_type)) { + GC_ADDREF(gc); } + ZEND_VM_NEXT_OPCODE(); } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_END_SILENCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } + if (E_HAS_ONLY_FATAL_ERRORS(EG(error_reporting)) + && !E_HAS_ONLY_FATAL_ERRORS(Z_LVAL_P(EX_VAR(opline->op1.var)))) { + EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var)); } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *value; + zend_reference *ref = NULL; + bool ret; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; + SAVE_OPLINE(); + value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(value)) { + if (IS_TMP_VAR == IS_VAR) { + ref = Z_REF_P(value); } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; + value = Z_REFVAL_P(value); + } + + ret = i_zend_is_true(value); + + if (UNEXPECTED(EG(exception))) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + + if (ret) { + zval *result = EX_VAR(opline->result.var); + + ZVAL_COPY_VALUE(result, value); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); + } else if (IS_TMP_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); + } else if (IS_TMP_VAR == IS_VAR && ref) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(result)) { + Z_ADDREF_P(result); } } + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - compare_function(EX_VAR(opline->result.var), op1, op2); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *value; + zend_reference *ref = NULL; SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - boolean_xor_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container, *dim, *value; + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + if (IS_TMP_VAR & IS_VAR) { + ref = Z_REF_P(value); + } + value = Z_REFVAL_P(value); + } - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R EXECUTE_DATA_CC); - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_array; - } else { - goto fetch_dim_r_slow; - } - } else { -fetch_dim_r_slow: - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; + if (Z_TYPE_P(value) > IS_NULL) { + zval *result = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(result, value); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); + } else if (IS_TMP_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); + } else if ((IS_TMP_VAR & IS_VAR) && ref) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(result)) { + Z_ADDREF_P(result); } - zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); } - } else { - zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + if ((IS_TMP_VAR & IS_VAR) && ref) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } + } + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_NULL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_IS(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - void **cache_slot = NULL; + zval *val, *result; - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if (Z_TYPE_P(val) > IS_NULL) { do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + if (Z_TYPE_P(val) <= IS_NULL) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); break; } } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_wrong_property_read(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_r_finish; + ZEND_VM_NEXT_OPCODE(); } while (0); } - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); - - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + result = EX_VAR(opline->result.var); + uint32_t short_circuiting_type = opline->extended_value & ZEND_SHORT_CIRCUITING_CHAIN_MASK; + if (EXPECTED(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { + ZVAL_NULL(result); + if (IS_TMP_VAR == IS_CV + && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF) + && (opline->extended_value & ZEND_JMP_NULL_BP_VAR_IS) == 0 + ) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + } else if (short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { + ZVAL_FALSE(result); + } else { + ZEND_ASSERT(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); + ZVAL_TRUE(result); + } - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_r_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { -fetch_obj_r_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - prop_offset = prop_info->offset; - goto fetch_obj_r_simple; - } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { - zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; - ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); - ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); +} - uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if ((IS_TMP_VAR|IS_VAR) & IS_CV) { - GC_ADDREF(zobj); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR|IS_TMP_VAR)) { - call_info |= ZEND_CALL_RELEASE_THIS; - } - zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); - call->prev_execute_data = execute_data; - call->call = NULL; - call->return_value = EX_VAR(opline->result.var); - call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + zval *result = EX_VAR(opline->result.var); - execute_data = call; - EG(current_execute_data) = execute_data; - zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); + value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } -#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) - opline = hook->op_array.opcodes; -#else - EX(opline) = hook->op_array.opcodes; -#endif - LOAD_OPLINE_EX(); + if (IS_TMP_VAR == IS_CV) { + ZVAL_COPY_DEREF(result, value); + } else if (IS_TMP_VAR == IS_VAR) { + if (UNEXPECTED(Z_ISREF_P(value))) { + ZVAL_COPY_VALUE(result, Z_REFVAL_P(value)); + if (UNEXPECTED(Z_DELREF_P(value) == 0)) { + efree_size(Z_REF_P(value), sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(result)) { + Z_ADDREF_P(result); + } + } else { + ZVAL_COPY_VALUE(result, value); + } + } else { + ZVAL_COPY_VALUE(result, value); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) { + Z_ADDREF_P(result); + } + } + } + ZEND_VM_NEXT_OPCODE(); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_FROM_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + zval *val; + SAVE_OPLINE(); + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator"); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } - ZEND_VM_ENTER_EX(); - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); +yield_from_try_again: + if (Z_TYPE_P(val) == IS_ARRAY) { + ZVAL_COPY_VALUE(&generator->values, val); + if (Z_OPT_REFCOUNTED_P(val)) { + Z_ADDREF_P(val); + } + Z_FE_POS(generator->values) = 0; + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } else if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) { + zend_class_entry *ce = Z_OBJCE_P(val); + if (ce == zend_ce_generator) { + zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + Z_ADDREF_P(val); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; - } - } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; - } - } + if (UNEXPECTED(new_gen->execute_data == NULL)) { + zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); + zval_ptr_dtor(val); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else if (Z_ISUNDEF(new_gen->retval)) { + if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) { + zend_throw_error(NULL, "Impossible to yield from the Generator being currently run"); + zval_ptr_dtor(val); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else { + zend_generator_yield_from(generator, new_gen); + } + } else { + if (RETURN_VALUE_USED(opline)) { + ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval); } + ZEND_VM_NEXT_OPCODE(); } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; + zend_object_iterator *iter = ce->get_iterator(ce, val, 0); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) { + if (!EG(exception)) { + zend_throw_error(NULL, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name)); + } + UNDEF_RESULT(); + HANDLE_EXCEPTION(); } - } -#if ZEND_DEBUG - /* For non-standard object handlers, verify a declared property type in debug builds. - * Fetch prop_info before calling read_property(), as it may deallocate the object. */ - zend_property_info *prop_info = NULL; - if (zobj->handlers->read_property != zend_std_read_property) { - prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); - } -#endif - retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); -#if ZEND_DEBUG - if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { - ZVAL_OPT_DEREF(retval); - zend_verify_property_type(prop_info, retval, /* strict */ true); - } -#endif + iter->index = 0; + if (iter->funcs->rewind) { + iter->funcs->rewind(iter); + if (UNEXPECTED(EG(exception) != NULL)) { + OBJ_RELEASE(&iter->std); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); + ZVAL_OBJ(&generator->values, &iter->std); } + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + goto yield_from_try_again; + } else { + zend_throw_error(NULL, "Can use \"yield from\" only with arrays and Traversables"); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_r_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } - } while (0); + /* This is the default return value + * when the expression is a Generator, it will be overwritten in zend_generator_resume() */ + if (RETURN_VALUE_USED(opline)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } -fetch_obj_r_finish: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + /* This generator has no send target (though the generator we delegate to might have one) */ + generator->send_target = NULL; + + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); + + ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_STRLEN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - void **cache_slot = NULL; + zval *value; - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(value); + } + ZEND_VM_NEXT_OPCODE(); + } else { + bool strict; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) { + value = Z_REFVAL_P(value); + if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + value = ZVAL_UNDEFINED_OP1(); + } + strict = EX_USES_STRICT_TYPES(); do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + if (EXPECTED(!strict)) { + zend_string *str; + zval tmp; + + if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) { + zend_error(E_DEPRECATED, + "strlen(): Passing null to parameter #1 ($string) of type string is deprecated"); + ZVAL_LONG(EX_VAR(opline->result.var), 0); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + break; + } + + ZVAL_COPY(&tmp, value); + if (zend_parse_arg_str_weak(&tmp, &str, 1)) { + ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str)); + zval_ptr_dtor(&tmp); break; } + zval_ptr_dtor(&tmp); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); + if (!EG(exception)) { + zend_type_error("strlen(): Argument #1 ($string) must be of type string, %s given", zend_zval_value_name(value)); } - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_is_finish; + ZVAL_UNDEF(EX_VAR(opline->result.var)); } while (0); } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value); - - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_TYPE_CHECK_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + int result = 0; - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_is_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { -fetch_obj_is_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - goto fetch_obj_is_simple; - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { +type_check_resource: + if (opline->extended_value != MAY_BE_RESOURCE + || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) { + result = 1; + } + } else if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) { + value = Z_REFVAL_P(value); + if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { + goto type_check_resource; + } + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + result = ((1 << IS_NULL) & opline->extended_value) != 0; + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); + } else { + ZEND_VM_SMART_BRANCH(result, 0); + } +} - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + uint32_t fetch_type; + zend_class_entry *called_scope, *scope; + USE_OPLINE - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } - } - } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { + if (IS_TMP_VAR != IS_UNUSED) { + SAVE_OPLINE(); + zval *op = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(Z_TYPE_P(op) != IS_OBJECT)) { + ZVAL_DEREF(op); + if (Z_TYPE_P(op) != IS_OBJECT) { + zend_type_error("Cannot use \"::class\" on %s", zend_zval_value_name(op)); ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); } } - retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op)->name); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_is_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } - } while (0); + fetch_type = opline->op1.num; + scope = EX(func)->op_array.scope; + if (UNEXPECTED(scope == NULL)) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", + fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : + fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } -fetch_obj_is_finish: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + switch (fetch_type) { + case ZEND_FETCH_CLASS_SELF: + ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->name); + break; + case ZEND_FETCH_CLASS_PARENT: + if (UNEXPECTED(scope->parent == NULL)) { + SAVE_OPLINE(); + zend_throw_error(NULL, + "Cannot use \"parent\" when current class scope has no parent"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->parent->name); + break; + case ZEND_FETCH_CLASS_STATIC: + if (Z_TYPE(EX(This)) == IS_OBJECT) { + called_scope = Z_OBJCE(EX(This)); + } else { + called_scope = Z_CE(EX(This)); + } + ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name); + break; + EMPTY_SWITCH_DEFAULT_CASE() + } + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - zend_string *op1_str, *op2_str, *str; - - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + div_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + pow_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + + if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); zend_string *str; uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); } else { ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op1_str, 0); } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && + } else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV && !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { size_t len = ZSTR_LEN(op1_str); + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { + zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); + } str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); GC_ADD_FLAGS(str, flags); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } else { @@ -18560,1415 +18342,1598 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_S memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); GC_ADD_FLAGS(str, flags); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op1_str, 0); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - op1_str = Z_STR_P(op1); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - op1_str = zend_string_copy(Z_STR_P(op1)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + SAVE_OPLINE(); + + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = ZVAL_UNDEFINED_OP1(); } - op1_str = zval_get_string_func(op1); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - op2_str = Z_STR_P(op2); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - op2_str = zend_string_copy(Z_STR_P(op2)); - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = ZVAL_UNDEFINED_OP2(); } - op2_str = zval_get_string_func(op2); + concat_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { - GC_ADDREF(op2_str); - } - } - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - zend_string_release_ex(op1_str, 0); - break; - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { - GC_ADDREF(op1_str); - } - } - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - zend_string_release_ex(op2_str, 0); - break; - } - } - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +} - ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release_ex(op1_str, 0); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release_ex(op2_str, 0); - } - } while (0); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_STRICT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zval *object; - zend_function *fbc; - zend_class_entry *called_scope; - zend_object *obj; - zend_execute_data *call; - uint32_t call_info; + zval *op1, *op2; + bool result; SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + result = fast_is_identical_function(op1, op2); - object = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Method name must be a string"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } while (0); - } + ZEND_VM_SMART_BRANCH(result, 1); +} - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - obj = Z_OBJ_P(object); - } else { - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - } else { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - zend_reference *ref = Z_REF_P(object); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - object = &ref->val; - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) & IS_VAR) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_ADDREF_P(object); - } - } - break; - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - object = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } - HANDLE_EXCEPTION(); - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - } - zend_invalid_method_call(object, function_name); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } while (0); - } + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + result = fast_is_not_identical_function(op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - called_scope = obj->ce; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else { - zend_object *orig_obj = obj; + ZEND_VM_SMART_BRANCH(result, 1); +} - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; - /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); } - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; } - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ - if (GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; + } } } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { - zend_objects_store_del(obj); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; } - /* call static method */ - obj = (zend_object*)called_scope; - call_info = ZEND_CALL_NESTED_FUNCTION; - } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; + } } - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } - - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, obj); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; double d1, d2; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -case_true: - ZEND_VM_SMART_BRANCH_TRUE(); +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); } else { -case_false: - ZEND_VM_SMART_BRANCH_FALSE(); +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); } } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { d1 = (double)Z_LVAL_P(op1); d2 = Z_DVAL_P(op2); - goto case_double; + goto is_equal_double; } } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { d1 = Z_DVAL_P(op1); d2 = Z_DVAL_P(op2); -case_double: +is_equal_double: if (d1 == d2) { - goto case_true; + goto is_equal_true; } else { - goto case_false; + goto is_equal_false; } } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { d1 = Z_DVAL_P(op1); d2 = (double)Z_LVAL_P(op2); - goto case_double; + goto is_equal_double; } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } if (result) { - goto case_true; + goto is_equal_true; } else { - goto case_false; + goto is_equal_false; } } } - ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - bool result; - zend_ulong hval; - zval *offset; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; - zval *value; - zend_string *str; + zval *op1, *op2; + double d1, d2; -isset_dim_obj_array: - ht = Z_ARRVAL_P(container); -isset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index_prop; - } - } - value = zend_hash_find_ex(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_prop: - value = zend_hash_index_find(ht, hval); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { - offset = Z_REFVAL_P(offset); - goto isset_again; - } else { - value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); - if (UNEXPECTED(EG(exception))) { - result = 0; - goto isset_dim_obj_exit; + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; } - - if (!(opline->extended_value & ZEND_ISEMPTY)) { - /* > IS_NULL means not IS_UNDEF and not IS_NULL */ - result = value != NULL && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - - if ((IS_TMP_VAR|IS_VAR) & (IS_CONST|IS_CV)) { - /* avoid exception check */ - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 0); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; } - } else { - result = (value == NULL || !i_zend_is_true(value)); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; } - goto isset_dim_obj_exit; - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto isset_dim_obj_array; + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } } } - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - if (!(opline->extended_value & ZEND_ISEMPTY)) { - result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); - } else { - result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); - } - -isset_dim_obj_exit: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - int result; - zval *offset; - zend_string *name, *tmp_name; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + zval *op1, *op2; + double d1, d2; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); } - } else { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; } - } - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(offset); - } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - result = 0; - goto isset_object_finish; + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } } } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } } - -isset_object_finish: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - - zval *key, *subject; - HashTable *ht; - bool result; + zval *op1, *op2; SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + compare_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - key = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - subject = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { -array_key_exists_array: - ht = Z_ARRVAL_P(subject); - result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); - } else { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { - subject = Z_REFVAL_P(subject); - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { - goto array_key_exists_array; - } - } - zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); - result = 0; - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_XOR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *expr; - bool result; + zval *op1, *op2; SAVE_OPLINE(); - expr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + boolean_xor_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); -try_instanceof: - if (Z_TYPE_P(expr) == IS_OBJECT) { - zend_class_entry *ce; - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(opline->extended_value); - if (UNEXPECTED(ce == NULL)) { - ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (EXPECTED(ce)) { - CACHE_PTR(opline->extended_value, ce); - } - } - } else if (IS_VAR == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ +#if 0 + USE_OPLINE +#endif + + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - result = ce && instanceof_function(Z_OBJCE_P(expr), ce); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { - expr = Z_REFVAL_P(expr); - goto try_instanceof; + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (IS_CONST == IS_UNUSED) { + ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - result = 0; + if (IS_TMP_VAR & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); } -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(ZEND_OPCODE_HANDLER_ARGS_EX int type) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { +#if 0 USE_OPLINE - zval *varname; - zval *retval; - zend_string *name, *tmp_name; - HashTable *target_symbol_table; - - SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); +#endif - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - tmp_name = NULL; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + /* Behave like FETCH_OBJ_W */ + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - name = zval_try_get_tmp_string(varname, &tmp_name); - if (UNEXPECTED(!name)) { - if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if (IS_TMP_VAR == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } } - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } +} - target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); - retval = zend_hash_find_ex(target_symbol_table, name, (IS_TMP_VAR|IS_VAR) == IS_CONST); - if (retval == NULL) { - if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { -fetch_this: - zend_fetch_this_var(type OPLINE_CC EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + zend_string *op1_str, *op2_str, *str; + + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + + if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - if (type == BP_VAR_W) { - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); - } else if (type == BP_VAR_IS || type == BP_VAR_UNSET) { - retval = &EG(uninitialized_zval); - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - /* Keep name alive in case an error handler tries to free it. */ - zend_string_addref(name); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); } - zend_error_unchecked(E_WARNING, "Undefined %svariable $%S", - (opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name); - if (type == BP_VAR_RW && !EG(exception)) { - retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); + } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { - retval = &EG(uninitialized_zval); + ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - zend_string_release(name); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); } - } - /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ - } else if (Z_TYPE_P(retval) == IS_INDIRECT) { - retval = Z_INDIRECT_P(retval); - if (Z_TYPE_P(retval) == IS_UNDEF) { - if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { - goto fetch_this; + } else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); } - if (type == BP_VAR_W) { - ZVAL_NULL(retval); - } else if (type == BP_VAR_IS || type == BP_VAR_UNSET) { - retval = &EG(uninitialized_zval); - } else { - zend_error_unchecked(E_WARNING, "Undefined %svariable $%S", - (opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name); - if (type == BP_VAR_RW && !EG(exception)) { - ZVAL_NULL(retval); - } else { - retval = &EG(uninitialized_zval); - } + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); } } + ZEND_VM_NEXT_OPCODE(); } - if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); + SAVE_OPLINE(); + if (IS_TMP_VAR == IS_CONST) { + op1_str = Z_STR_P(op1); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + op1_str = zend_string_copy(Z_STR_P(op1)); + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + op1_str = zval_get_string_func(op1); } - - ZEND_ASSERT(retval != NULL); - if (type == BP_VAR_R || type == BP_VAR_IS) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + if (IS_CONST == IS_CONST) { + op2_str = Z_STR_P(op2); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + op2_str = zend_string_copy(Z_STR_P(op2)); } else { - ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + } + op2_str = zval_get_string_func(op2); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW)); -} + do { + if (IS_TMP_VAR != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + zend_string_release_ex(op1_str, 0); + break; + } + } + if (IS_CONST != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + zend_string_release_ex(op2_str, 0); + break; + } + } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - int fetch_type = - (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ? - BP_VAR_W : BP_VAR_R; - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX fetch_type)); -} + ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR != IS_CONST) { + zend_string_release_ex(op1_str, 0); + } + if (IS_CONST != IS_CONST) { + zend_string_release_ex(op2_str, 0); + } + } while (0); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET)); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_ADD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value, *arg; + zend_string **rope; + zval *var; - if (IS_UNUSED == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - uint32_t arg_num; - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); + /* op1 and result are the same */ + rope = (zend_string**)EX_VAR(opline->op1.var); + if (IS_CONST == IS_CONST) { + var = RT_CONSTANT(opline, opline->op2); + rope[opline->extended_value] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); } } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - } + var = RT_CONSTANT(opline, opline->op2); + if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { + if (IS_CONST == IS_CV) { + rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); + } else { + rope[opline->extended_value] = Z_STR_P(var); + } + } else { + SAVE_OPLINE(); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + } + rope[opline->extended_value] = zval_get_string_func(var); - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(arg, value); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { - Z_ADDREF_P(arg); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } } ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_END_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *varname; - zend_string *name, *tmp_name; - HashTable *target_symbol_table; + zend_string **rope; + zval *var, *ret; + uint32_t i; - SAVE_OPLINE(); + rope = (zend_string**)EX_VAR(opline->op1.var); + if (IS_CONST == IS_CONST) { + var = RT_CONSTANT(opline, opline->op2); + rope[opline->extended_value] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); + } + } else { + var = RT_CONSTANT(opline, opline->op2); + if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { + if (IS_CONST == IS_CV) { + rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); + } else { + rope[opline->extended_value] = Z_STR_P(var); + } + } else { + SAVE_OPLINE(); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + } + rope[opline->extended_value] = zval_get_string_func(var); - varname = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - tmp_name = NULL; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = ZVAL_UNDEFINED_OP1(); - } - name = zval_try_get_tmp_string(varname, &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); + if (UNEXPECTED(EG(exception))) { + for (i = 0; i <= opline->extended_value; i++) { + zend_string_release_ex(rope[i], 0); + } + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } } } - target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); - zend_hash_del_ind(target_symbol_table, name); + size_t len = 0; + uint32_t flags = ZSTR_COPYABLE_CONCAT_PROPERTIES; + for (i = 0; i <= opline->extended_value; i++) { + flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]); + len += ZSTR_LEN(rope[i]); + } + ret = EX_VAR(opline->result.var); + ZVAL_STR(ret, zend_string_alloc(len, 0)); + GC_ADD_FLAGS(Z_STR_P(ret), flags); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); + char *target = Z_STRVAL_P(ret); + for (i = 0; i <= opline->extended_value; i++) { + memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i])); + target += ZSTR_LEN(rope[i]); + zend_string_release_ex(rope[i], 0); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + *target = '\0'; + + ZEND_VM_NEXT_OPCODE(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - bool result; - zval *varname; - zend_string *name, *tmp_name; - HashTable *target_symbol_table; + zval *function_name; + zval *object; + zend_function *fbc; + zend_class_entry *called_scope; + zend_object *obj; + zend_execute_data *call; + uint32_t call_info; SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(varname); - } else { - name = zval_get_tmp_string(varname, &tmp_name); - } - target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); - value = zend_hash_find_ex(target_symbol_table, name, (IS_TMP_VAR|IS_VAR) == IS_CONST); + object = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); + if (IS_CONST != IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - if (!value) { - result = (opline->extended_value & ZEND_ISEMPTY); - } else { - if (Z_TYPE_P(value) == IS_INDIRECT) { - value = Z_INDIRECT_P(value); - } - if (!(opline->extended_value & ZEND_ISEMPTY)) { - if (Z_ISREF_P(value)) { - value = Z_REFVAL_P(value); + if (IS_CONST != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } } - result = Z_TYPE_P(value) > IS_NULL; - } else { - result = !i_zend_is_true(value); - } - } + zend_throw_error(NULL, "Method name must be a string"); - ZEND_VM_SMART_BRANCH(result, true); -} -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *expr; - bool result; + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } while (0); + } - SAVE_OPLINE(); - expr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_UNUSED) { + obj = Z_OBJ_P(object); + } else { + do { + if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + } else { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + zend_reference *ref = Z_REF_P(object); -try_instanceof: - if (Z_TYPE_P(expr) == IS_OBJECT) { - zend_class_entry *ce; + object = &ref->val; + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + if (IS_TMP_VAR & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } + break; + } + } + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + object = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_CONST != IS_CONST) { - if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(opline->extended_value); - if (UNEXPECTED(ce == NULL)) { - ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (EXPECTED(ce)) { - CACHE_PTR(opline->extended_value, ce); + + } + HANDLE_EXCEPTION(); + } } - } - } else if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } + zend_invalid_method_call(object, function_name); + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - result = ce && instanceof_function(Z_OBJCE_P(expr), ce); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { - expr = Z_REFVAL_P(expr); - goto try_instanceof; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - result = 0; + } while (0); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COUNT_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1; - zend_long count; + called_scope = obj->ce; - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (IS_CONST == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else { + zend_object *orig_obj = obj; - while (1) { - if (Z_TYPE_P(op1) == IS_ARRAY) { - count = zend_hash_num_elements(Z_ARRVAL_P(op1)); - break; - } else if (Z_TYPE_P(op1) == IS_OBJECT) { - zend_object *zobj = Z_OBJ_P(op1); + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } - /* first, we check if the handler is defined */ - if (zobj->handlers->count_elements) { - if (SUCCESS == zobj->handlers->count_elements(zobj, &count)) { - break; - } - if (UNEXPECTED(EG(exception))) { - count = 0; - break; - } + /* First, locate the function. */ + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); } - /* if not and the object implements Countable we call its count() method */ - if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) { - zval retval; - zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT)); - zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval); - count = zval_get_long(&retval); - zval_ptr_dtor(&retval); - break; + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); } - - /* If There's no handler and it doesn't implement Countable then emit a TypeError */ - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - continue; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + HANDLE_EXCEPTION(); + } + if (IS_CONST == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(obj == orig_obj)) { + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); + } + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); } - count = 0; - zend_type_error("%s(): Argument #1 ($value) must be of type Countable|array, %s given", opline->extended_value ? "sizeof" : "count", zend_zval_value_name(op1)); - break; } - ZVAL_LONG(EX_VAR(opline->result.var), count); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + if (IS_CONST != IS_CONST) { -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_array *ht = Z_ARRVAL_P(_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)); - ZVAL_LONG(EX_VAR(opline->result.var), zend_hash_num_elements(ht)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR) && !(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - SAVE_OPLINE(); - zend_array_destroy(ht); - if (EG(exception)) { - HANDLE_EXCEPTION(); + + } + + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; + } else if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR|IS_CV)) { + if (IS_TMP_VAR == IS_CV) { + GC_ADDREF(obj); /* For $this pointer */ } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } + + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, obj); + call->prev_execute_data = EX(call); + EX(call) = call; + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_EX_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *value, *arg; + uint32_t arg_num; - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_CONST == IS_CONST) { SAVE_OPLINE(); - if (UNEXPECTED(!EX(func)->common.scope)) { - zend_throw_error(NULL, "get_class() without arguments must be called from within a class"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); HANDLE_EXCEPTION(); - } else { - zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated"); - ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); } } else { - zval *op1; + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + arg_num = opline->op2.num; + } - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - while (1) { - if (Z_TYPE_P(op1) == IS_OBJECT) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - continue; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_type_error("get_class(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(op1)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - } - break; + if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) { + if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_val_by_ref; + } + } else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { +send_val_by_ref:; + ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg)); + } + value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(arg, value); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { + Z_ADDREF_P(arg); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zval *result = EX_VAR(opline->result.var); - ZVAL_COPY(result, value); ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; + double d1, d2; - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - div_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +case_true: + ZEND_VM_SMART_BRANCH_TRUE(); + } else { +case_false: + ZEND_VM_SMART_BRANCH_FALSE(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto case_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +case_double: + if (d1 == d2) { + goto case_true; + } else { + goto case_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto case_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + if (result) { + goto case_true; + } else { + goto case_false; + } + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *expr_ptr, new_expr; SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - pow_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; + if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && + UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { + expr_ptr = zend_get_bad_ptr(); + if (Z_ISREF_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } else { + ZVAL_MAKE_REF_EX(expr_ptr, 2); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } else { + expr_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_TMP_VAR) { + /* pass */ + } else if (IS_TMP_VAR == IS_CONST) { + Z_TRY_ADDREF_P(expr_ptr); + } else if (IS_TMP_VAR == IS_CV) { + ZVAL_DEREF(expr_ptr); + Z_TRY_ADDREF_P(expr_ptr); + } else /* if (IS_TMP_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(expr_ptr); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_VAR(opline->op2.var); + expr_ptr = Z_REFVAL_P(expr_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + ZVAL_COPY_VALUE(&new_expr, expr_ptr); + expr_ptr = &new_expr; + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } + } + } + } - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); + if (IS_CONST != IS_UNUSED) { + zval *offset = RT_CONSTANT(opline, opline->op2); zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + zend_ulong hval; - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CV == IS_CONST || IS_CV == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); +add_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_CONST != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index; + } } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); +str_index: + zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index: + zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto add_again; + } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { + zval tmp; + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_COPY(&tmp, expr_ptr); } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { - zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + /* A userland error handler can do funky things to the expression, so reset it */ + zval_ptr_dtor(expr_ptr); + ZVAL_COPY_VALUE(expr_ptr, &tmp); } - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); + if (UNEXPECTED(EG(exception))) { + zval_ptr_dtor_nogc(expr_ptr); + HANDLE_EXCEPTION(); } + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + goto num_index; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); + hval = Z_RES_HANDLE_P(offset); + goto num_index; + } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + str = ZSTR_EMPTY_ALLOC(); + goto str_index; } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } - ZEND_VM_NEXT_OPCODE(); - } else { - SAVE_OPLINE(); - - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = ZVAL_UNDEFINED_OP1(); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = ZVAL_UNDEFINED_OP2(); + zend_illegal_array_offset_access(offset); + zval_ptr_dtor_nogc(expr_ptr); } - concat_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(expr_ptr); + } } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zval *array; + uint32_t size; USE_OPLINE - zval *op1, *op2; SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - compare_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + array = EX_VAR(opline->result.var); + if (IS_TMP_VAR != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_ARR(array, zend_new_array(0)); + ZEND_VM_NEXT_OPCODE(); + } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container, *dim, *value; + zval *container; + bool result; + zend_ulong hval; + zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - dim = EX_VAR(opline->op2.var); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R EXECUTE_DATA_CC); - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_array; - } else { - goto fetch_dim_r_slow; + container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + offset = RT_CONSTANT(opline, opline->op2); + + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + zval *value; + zend_string *str; + +isset_dim_obj_array: + ht = Z_ARRVAL_P(container); +isset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_CONST != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_prop; + } } + value = zend_hash_find_ex(ht, str, IS_CONST == IS_CONST); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_prop: + value = zend_hash_index_find(ht, hval); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + offset = Z_REFVAL_P(offset); + goto isset_again; } else { -fetch_dim_r_slow: - if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; + value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); + if (UNEXPECTED(EG(exception))) { + result = 0; + goto isset_dim_obj_exit; } - zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); } - } else { - zend_fetch_dimension_address_read_R(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC); - } + if (!(opline->extended_value & ZEND_ISEMPTY)) { + /* > IS_NULL means not IS_UNDEF and not IS_NULL */ + result = value != NULL && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + if (IS_TMP_VAR & (IS_CONST|IS_CV)) { + /* avoid exception check */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_IS(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); + ZEND_VM_SMART_BRANCH(result, 0); + } + } else { + result = (value == NULL || !i_zend_is_true(value)); + } + goto isset_dim_obj_exit; + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto isset_dim_obj_array; + } + } + + if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; + } + if (!(opline->extended_value & ZEND_ISEMPTY)) { + result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); + } else { + result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); + } + +isset_dim_obj_exit: zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; - void **cache_slot = NULL; + int result; + zval *offset; + zend_string *name, *tmp_name; SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + offset = RT_CONSTANT(opline, opline->op2); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - break; - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (IS_TMP_VAR == IS_CONST || + (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } - zend_wrong_property_read(container, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_r_finish; - } while (0); + } else { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } } - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; - - if (IS_CV == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); - - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(offset); + } else { + name = zval_try_get_tmp_string(offset, &tmp_name); + if (UNEXPECTED(!name)) { + result = 0; + goto isset_object_finish; + } + } - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_r_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { -fetch_obj_r_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - prop_offset = prop_info->offset; - goto fetch_obj_r_simple; - } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { - zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; - ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); - ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if ((IS_TMP_VAR|IS_VAR) & IS_CV) { - GC_ADDREF(zobj); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR|IS_TMP_VAR)) { - call_info |= ZEND_CALL_RELEASE_THIS; - } - zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); - call->prev_execute_data = execute_data; - call->call = NULL; - call->return_value = EX_VAR(opline->result.var); - call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } - execute_data = call; - EG(current_execute_data) = execute_data; - zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); +isset_object_finish: -#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) - opline = hook->op_array.opcodes; -#else - EX(opline) = hook->op_array.opcodes; -#endif - LOAD_OPLINE_EX(); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *key, *subject; + HashTable *ht; + bool result; - ZEND_VM_ENTER_EX(); - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + SAVE_OPLINE(); - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + key = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + subject = RT_CONSTANT(opline, opline->op2); - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; - } - } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; - } - } - } - } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: + ht = Z_ARRVAL_P(subject); + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); + } else { + if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; } } - -#if ZEND_DEBUG - /* For non-standard object handlers, verify a declared property type in debug builds. - * Fetch prop_info before calling read_property(), as it may deallocate the object. */ - zend_property_info *prop_info = NULL; - if (zobj->handlers->read_property != zend_std_read_property) { - prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); - } -#endif - retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); -#if ZEND_DEBUG - if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { - ZVAL_OPT_DEREF(retval); - zend_verify_property_type(prop_info, retval, /* strict */ true); - } -#endif - - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_r_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } - } while (0); - -fetch_obj_r_finish: + zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); + result = 0; + } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - void **cache_slot = NULL; + zval *expr; + bool result; SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - break; +try_instanceof: + if (Z_TYPE_P(expr) == IS_OBJECT) { + zend_class_entry *ce; + + if (IS_CONST == IS_CONST) { + ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (EXPECTED(ce)) { + CACHE_PTR(opline->extended_value, ce); } } - if (IS_CV == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_is_finish; - } while (0); + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { + expr = Z_REFVAL_P(expr); + goto try_instanceof; + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + result = 0; } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE - if (IS_CV == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value); + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + SAVE_OPLINE(); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_is_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { -fetch_obj_is_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - goto fetch_obj_is_simple; - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + /* Set the new yielded value */ + if (IS_TMP_VAR != IS_UNUSED) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) { + zval *value; + + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + + value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; + } + } else { + zval *value_ptr = zend_get_bad_ptr(); + + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + do { + if (IS_TMP_VAR == IS_VAR) { + ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION + && !Z_ISREF_P(value_ptr)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + ZVAL_COPY(&generator->value, value_ptr); + break; } } - } + if (Z_ISREF_P(value_ptr)) { + Z_ADDREF_P(value_ptr); + } else { + ZVAL_MAKE_REF_EX(value_ptr, 2); + } + ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); + } while (0); + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; + zval *value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + /* Consts, temporary variables and references need copying */ + if (IS_TMP_VAR == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } else if (IS_TMP_VAR == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + + + } else { + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_TMP_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } } } + } else { + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); + } - retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + /* Set the new yielded key */ + if (IS_CONST != IS_UNUSED) { + zval *key = RT_CONSTANT(opline, opline->op2); + if ((IS_CONST & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + key = Z_REFVAL_P(key); } + ZVAL_COPY(&generator->key, key); - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_is_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); + + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); } - } while (0); + } else { + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); + } -fetch_obj_is_finish: + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; + } + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - zend_string *op1_str, *op2_str, *str; + zval *op1; + HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); + zval *result; + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_TMP_VAR == IS_CONST); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + ZEND_VM_SMART_BRANCH(result, 0); + } - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_VAR(opline->op2.var); - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); + if (opline->extended_value) { + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + result = zend_hash_index_find(ht, Z_LVAL_P(op1)); + ZEND_VM_SMART_BRANCH(result, 0); + } + SAVE_OPLINE(); + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find(ht, Z_STR_P(op1)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 0); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + result = zend_hash_index_find(ht, Z_LVAL_P(op1)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 0); + } + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + } else if (Z_TYPE_P(op1) <= IS_FALSE) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + result = zend_hash_find_known_hash(ht, ZSTR_EMPTY_ALLOC()); + ZEND_VM_SMART_BRANCH(result, 0); + } else { + zend_string *key; + zval key_tmp; + + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find(ht, Z_STR_P(op1)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 0); + } + } + + SAVE_OPLINE(); + ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) { + ZVAL_STR(&key_tmp, key); + if (zend_compare(op1, &key_tmp) == 0) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(1, 1); + } + } ZEND_HASH_FOREACH_END(); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(0, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + div_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + pow_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); zend_string *op2_str = Z_STR_P(op2); zend_string *str; uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CV == IS_CONST || IS_CV == IS_CV) { + if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); } else { ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op1_str, 0); } - } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + } else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && + } else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV && !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { size_t len = ZSTR_LEN(op1_str); + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { + zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); + } str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); GC_ADD_FLAGS(str, flags); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } else { @@ -19977,1274 +19942,1674 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_S memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); GC_ADD_FLAGS(str, flags); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op1_str, 0); } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - op1_str = Z_STR_P(op1); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - op1_str = zend_string_copy(Z_STR_P(op1)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + SAVE_OPLINE(); + + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = ZVAL_UNDEFINED_OP1(); } - op1_str = zval_get_string_func(op1); - } - if (IS_CV == IS_CONST) { - op2_str = Z_STR_P(op2); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - op2_str = zend_string_copy(Z_STR_P(op2)); - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = ZVAL_UNDEFINED_OP2(); } - op2_str = zval_get_string_func(op2); + concat_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { - GC_ADDREF(op2_str); - } - } - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - zend_string_release_ex(op1_str, 0); - break; - } - } - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { - GC_ADDREF(op1_str); - } - } - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - zend_string_release_ex(op2_str, 0); - break; - } - } - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); +} - ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CV != IS_CONST) { - zend_string_release_ex(op2_str, 0); - } - } while (0); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + result = fast_is_identical_function(op1, op2); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_STRICT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + result = fast_is_identical_function(op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zval *object; - zend_function *fbc; - zend_class_entry *called_scope; - zend_object *obj; - zend_execute_data *call; - uint32_t call_info; + zval *op1, *op2; + bool result; SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + result = fast_is_not_identical_function(op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} - object = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV != IS_CONST) { - function_name = EX_VAR(opline->op2.var); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; - if (IS_CV != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); } - zend_throw_error(NULL, "Method name must be a string"); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } while (0); - } - - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - obj = Z_OBJ_P(object); - } else { - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; } else { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - zend_reference *ref = Z_REF_P(object); - - object = &ref->val; - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) & IS_VAR) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_ADDREF_P(object); - } - } - break; - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - object = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CV != IS_CONST) { - - - } - HANDLE_EXCEPTION(); - } - } - if (IS_CV == IS_CONST) { - function_name = EX_VAR(opline->op2.var); - } - zend_invalid_method_call(object, function_name); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); + goto is_equal_false; } - } while (0); - } - - called_scope = obj->ce; - - if (IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else { - zend_object *orig_obj = obj; - - if (IS_CV == IS_CONST) { - function_name = EX_VAR(opline->op2.var); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; } - - /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); } - - - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); } - HANDLE_EXCEPTION(); - } - if (IS_CV == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); - } - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ - if (GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; } } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} - if (IS_CV != IS_CONST) { - - - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { - zend_objects_store_del(obj); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; } - /* call static method */ - obj = (zend_object*)called_scope; - call_info = ZEND_CALL_NESTED_FUNCTION; - } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; + } } - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } - - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, obj); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; double d1, d2; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_VAR(opline->op2.var); - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -case_true: - ZEND_VM_SMART_BRANCH_TRUE(); +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); } else { -case_false: - ZEND_VM_SMART_BRANCH_FALSE(); +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); } } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { d1 = (double)Z_LVAL_P(op1); d2 = Z_DVAL_P(op2); - goto case_double; + goto is_equal_double; } } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { d1 = Z_DVAL_P(op1); d2 = Z_DVAL_P(op2); -case_double: +is_equal_double: if (d1 == d2) { - goto case_true; + goto is_equal_true; } else { - goto case_false; + goto is_equal_false; } } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { d1 = Z_DVAL_P(op1); d2 = (double)Z_LVAL_P(op2); - goto case_double; + goto is_equal_double; } } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - - + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } if (result) { - goto case_true; + goto is_equal_true; } else { - goto case_false; + goto is_equal_false; } } } - ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - bool result; - zend_ulong hval; - zval *offset; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = EX_VAR(opline->op2.var); - - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; - zval *value; - zend_string *str; + zval *op1, *op2; + double d1, d2; -isset_dim_obj_array: - ht = Z_ARRVAL_P(container); -isset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_CV != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index_prop; - } + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); } - value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_prop: - value = zend_hash_index_find(ht, hval); - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { - offset = Z_REFVAL_P(offset); - goto isset_again; - } else { - value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); - if (UNEXPECTED(EG(exception))) { - result = 0; - goto isset_dim_obj_exit; + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; } - - if (!(opline->extended_value & ZEND_ISEMPTY)) { - /* > IS_NULL means not IS_UNDEF and not IS_NULL */ - result = value != NULL && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - - if ((IS_TMP_VAR|IS_VAR) & (IS_CONST|IS_CV)) { - /* avoid exception check */ - - - ZEND_VM_SMART_BRANCH(result, 0); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; } - } else { - result = (value == NULL || !i_zend_is_true(value)); - } - goto isset_dim_obj_exit; - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto isset_dim_obj_array; } } - - if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - if (!(opline->extended_value & ZEND_ISEMPTY)) { - result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); - } else { - result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); - } - -isset_dim_obj_exit: - - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - int result; - zval *offset; - zend_string *name, *tmp_name; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + zval *op1, *op2; + double d1, d2; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); } - } else { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; } - } - - if (IS_CV == IS_CONST) { - name = Z_STR_P(offset); - } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - result = 0; - goto isset_object_finish; + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } } } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} -isset_object_finish: - +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + compare_function(EX_VAR(opline->result.var), op1, op2); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_XOR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - - zval *key, *subject; - HashTable *ht; - bool result; + zval *op1, *op2; SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + boolean_xor_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - key = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - subject = EX_VAR(opline->op2.var); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ +#if 0 + USE_OPLINE +#endif - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { -array_key_exists_array: - ht = Z_ARRVAL_P(subject); - result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { - subject = Z_REFVAL_P(subject); - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { - goto array_key_exists_array; + if (IS_TMP_VAR == IS_UNUSED) { + ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + if (IS_TMP_VAR & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } } } - zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); - result = 0; + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { +#if 0 USE_OPLINE - zval *retval_ptr; - zval *return_value; - - - retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - return_value = EX(return_value); - +#endif - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) { - SAVE_OPLINE(); - retval_ptr = ZVAL_UNDEFINED_OP1(); - if (return_value) { - ZVAL_NULL(return_value); - } - } else if (!return_value) { - if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) { - if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) { - SAVE_OPLINE(); - rc_dtor_func(Z_COUNTED_P(retval_ptr)); - } + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + /* Behave like FETCH_OBJ_W */ + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) { - Z_ADDREF_P(return_value); - } - } - } else if (IS_TMP_VAR == IS_CV) { - do { - if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { - zend_refcounted *ref = Z_COUNTED_P(retval_ptr); - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (GC_MAY_LEAK(ref)) { - SAVE_OPLINE(); - gc_possible_root(ref); - } - ZVAL_NULL(retval_ptr); - break; - } else { - Z_ADDREF_P(retval_ptr); - } - } else { - retval_ptr = Z_REFVAL_P(retval_ptr); - if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } - } - } - ZVAL_COPY_VALUE(return_value, retval_ptr); - } while (0); - } else /* if (IS_TMP_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(retval_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(retval_ptr); - - retval_ptr = Z_REFVAL_P(retval_ptr); - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { + if (IS_TMP_VAR == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); + } else { + Z_TRY_ADDREF_P(op1); } - } else { - ZVAL_COPY_VALUE(return_value, retval_ptr); } } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - - - - - - - ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *retval_ptr; - zval *return_value; + zval *op1, *op2; + zend_string *op1_str, *op2_str, *str; - SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); - return_value = EX(return_value); + if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + } else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } + ZEND_VM_NEXT_OPCODE(); + } + SAVE_OPLINE(); + if (IS_TMP_VAR == IS_CONST) { + op1_str = Z_STR_P(op1); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + op1_str = zend_string_copy(Z_STR_P(op1)); + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + op1_str = zval_get_string_func(op1); + } + if (IS_TMP_VAR == IS_CONST) { + op2_str = Z_STR_P(op2); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + op2_str = zend_string_copy(Z_STR_P(op2)); + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + } + op2_str = zval_get_string_func(op2); + } do { - if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) || - (IS_TMP_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { - /* Not supposed to happen, but we'll allow it */ - zend_error(E_NOTICE, "Only variable references should be returned by reference"); - - retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if (!return_value) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } else { - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) { - ZVAL_COPY_VALUE(return_value, retval_ptr); - break; - } - - ZVAL_NEW_REF(return_value, retval_ptr); + if (IS_TMP_VAR != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { if (IS_TMP_VAR == IS_CONST) { - Z_TRY_ADDREF_P(retval_ptr); + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } } + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + zend_string_release_ex(op1_str, 0); + break; } - break; } - - retval_ptr = zend_get_bad_ptr(); - - if (IS_TMP_VAR == IS_VAR) { - ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) { - zend_error(E_NOTICE, "Only variable references should be returned by reference"); - if (return_value) { - ZVAL_NEW_REF(return_value, retval_ptr); - } else { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (IS_TMP_VAR != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } } + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + zend_string_release_ex(op2_str, 0); break; } } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - if (return_value) { - if (Z_ISREF_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } else { - ZVAL_MAKE_REF_EX(retval_ptr, 2); - } - ZVAL_REF(return_value, Z_REF_P(retval_ptr)); + ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR != IS_CONST) { + zend_string_release_ex(op1_str, 0); + } + if (IS_TMP_VAR != IS_CONST) { + zend_string_release_ex(op2_str, 0); } - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); } while (0); - - - - - ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GENERATOR_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_ADD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *retval; - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - - SAVE_OPLINE(); - retval = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + zend_string **rope; + zval *var; - /* Copy return value into generator->retval */ - if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { - ZVAL_COPY_VALUE(&generator->retval, retval); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) { - Z_ADDREF(generator->retval); - } + /* op1 and result are the same */ + rope = (zend_string**)EX_VAR(opline->op1.var); + if (IS_TMP_VAR == IS_CONST) { + var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + rope[opline->extended_value] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); } - } else if (IS_TMP_VAR == IS_CV) { - ZVAL_COPY_DEREF(&generator->retval, retval); - } else /* if (IS_TMP_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_refcounted *ref = Z_COUNTED_P(retval); - - retval = Z_REFVAL_P(retval); - ZVAL_COPY_VALUE(&generator->retval, retval); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(retval)) { - Z_ADDREF_P(retval); + } else { + var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { + if (IS_TMP_VAR == IS_CV) { + rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); + } else { + rope[opline->extended_value] = Z_STR_P(var); } } else { - ZVAL_COPY_VALUE(&generator->retval, retval); + SAVE_OPLINE(); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + } + rope[opline->extended_value] = zval_get_string_func(var); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } } - - - EG(current_execute_data) = EX(prev_execute_data); - - /* Close the generator to free up resources */ - zend_generator_close(generator, 1); - - /* Pass execution back to handling code */ - ZEND_VM_RETURN(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_USER_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_END_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *arg, *param; - - SAVE_OPLINE(); - - arg = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - param = ZEND_CALL_VAR(EX(call), opline->result.var); - if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) { - zend_param_must_be_ref(EX(call)->func, opline->op2.num); - Z_TRY_ADDREF_P(arg); - ZVAL_NEW_REF(param, arg); - } else { - ZVAL_COPY(param, arg); - } + zend_string **rope; + zval *var, *ret; + uint32_t i; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *expr; - zval *result = EX_VAR(opline->result.var); - - SAVE_OPLINE(); - expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - - switch (opline->extended_value) { - case IS_LONG: - ZVAL_LONG(result, zval_get_long(expr)); - break; - case IS_DOUBLE: - ZVAL_DOUBLE(result, zval_get_double(expr)); - break; - case IS_STRING: - ZVAL_STR(result, zval_get_string(expr)); - break; - default: - ZEND_ASSERT(opline->extended_value != _IS_BOOL && "Must use ZEND_BOOL instead"); - if (IS_TMP_VAR & (IS_VAR|IS_CV)) { - ZVAL_DEREF(expr); + rope = (zend_string**)EX_VAR(opline->op1.var); + if (IS_TMP_VAR == IS_CONST) { + var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + rope[opline->extended_value] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); + } + } else { + var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { + if (IS_TMP_VAR == IS_CV) { + rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); + } else { + rope[opline->extended_value] = Z_STR_P(var); } - /* If value is already of correct type, return it directly */ - if (Z_TYPE_P(expr) == opline->extended_value) { - ZVAL_COPY_VALUE(result, expr); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_TMP_VAR != IS_TMP_VAR) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); + } else { + SAVE_OPLINE(); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + } + rope[opline->extended_value] = zval_get_string_func(var); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (UNEXPECTED(EG(exception))) { + for (i = 0; i <= opline->extended_value; i++) { + zend_string_release_ex(rope[i], 0); } - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } + } + } - if (opline->extended_value == IS_ARRAY) { - zend_cast_zval_to_array(result, expr, IS_TMP_VAR); - } else { - ZEND_ASSERT(opline->extended_value == IS_OBJECT); - zend_cast_zval_to_object(result, expr, IS_TMP_VAR); - } + size_t len = 0; + uint32_t flags = ZSTR_COPYABLE_CONCAT_PROPERTIES; + for (i = 0; i <= opline->extended_value; i++) { + flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]); + len += ZSTR_LEN(rope[i]); } + ret = EX_VAR(opline->result.var); + ZVAL_STR(ret, zend_string_alloc(len, 0)); + GC_ADD_FLAGS(Z_STR_P(ret), flags); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + char *target = Z_STRVAL_P(ret); + for (i = 0; i <= opline->extended_value; i++) { + memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i])); + target += ZSTR_LEN(rope[i]); + zend_string_release_ex(rope[i], 0); + } + *target = '\0'; + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *array_ptr, *result; + zval *function_name; + zval *object; + zend_function *fbc; + zend_class_entry *called_scope; + zend_object *obj; + zend_execute_data *call; + uint32_t call_info; SAVE_OPLINE(); - array_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { - result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, array_ptr); - if (IS_TMP_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(array_ptr); - } - Z_FE_POS_P(result) = 0; - - - ZEND_VM_NEXT_OPCODE(); - } else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { - zend_object *zobj = Z_OBJ_P(array_ptr); - if (!zobj->ce->get_iterator) { - if (UNEXPECTED(zend_object_is_lazy(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (UNEXPECTED(EG(exception))) { - UNDEF_RESULT(); + object = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR != IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + } + if (IS_TMP_VAR != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); HANDLE_EXCEPTION(); } } - HashTable *properties = zobj->properties; - if (properties) { - if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(properties); + zend_throw_error(NULL, "Method name must be a string"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } while (0); + } + + if (IS_TMP_VAR == IS_UNUSED) { + obj = Z_OBJ_P(object); + } else { + do { + if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + } else { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + if (IS_TMP_VAR & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } + break; } - properties = zobj->properties = zend_array_dup(properties); } - } else { - properties = zobj->handlers->get_properties(zobj); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + object = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_TMP_VAR != IS_CONST) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } + HANDLE_EXCEPTION(); + } + } + if (IS_TMP_VAR == IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + } + zend_invalid_method_call(object, function_name); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); } + } while (0); + } - result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, array_ptr); - if (IS_TMP_VAR != IS_TMP_VAR) { - Z_ADDREF_P(array_ptr); - } + called_scope = obj->ce; - if (zend_hash_num_elements(properties) == 0) { - Z_FE_ITER_P(result) = (uint32_t) -1; + if (IS_TMP_VAR == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else { + zend_object *orig_obj = obj; + if (IS_TMP_VAR == IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + } - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + /* First, locate the function. */ + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + HANDLE_EXCEPTION(); + } + if (IS_TMP_VAR == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(obj == orig_obj)) { + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); + } + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + } - Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); + if (IS_TMP_VAR != IS_CONST) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); - } else if (is_empty) { - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else { - ZEND_VM_NEXT_OPCODE(); } } - } else { - zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; + } else if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR|IS_CV)) { + if (IS_TMP_VAR == IS_CV) { + GC_ADDREF(obj); /* For $this pointer */ + } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } + + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, obj); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *array_ptr, *array_ref; - - SAVE_OPLINE(); + zval *op1, *op2; + double d1, d2; - if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - array_ref = array_ptr = zend_get_bad_ptr(); - if (Z_ISREF_P(array_ref)) { - array_ptr = Z_REFVAL_P(array_ref); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +case_true: + ZEND_VM_SMART_BRANCH_TRUE(); + } else { +case_false: + ZEND_VM_SMART_BRANCH_FALSE(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto case_double; } - } else { - array_ref = array_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - } - - if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { - if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - if (array_ptr == array_ref) { - ZVAL_NEW_REF(array_ref, array_ref); - array_ptr = Z_REFVAL_P(array_ref); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +case_double: + if (d1 == d2) { + goto case_true; + } else { + goto case_false; } - Z_ADDREF_P(array_ref); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); - } else { - array_ref = EX_VAR(opline->result.var); - ZVAL_NEW_REF(array_ref, array_ptr); - array_ptr = Z_REFVAL_P(array_ref); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto case_double; } - if (IS_TMP_VAR == IS_CONST) { - ZVAL_ARR(array_ptr, zend_array_dup(Z_ARRVAL_P(array_ptr))); - } else { - SEPARATE_ARRAY(array_ptr); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (result) { + goto case_true; + } else { + goto case_false; + } } - Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0); - + } + ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} - ZEND_VM_NEXT_OPCODE(); - } else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { - if (!Z_OBJCE_P(array_ptr)->get_iterator) { - zend_object *zobj = Z_OBJ_P(array_ptr); - HashTable *properties; - if (UNEXPECTED(zend_object_is_lazy(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (UNEXPECTED(EG(exception))) { - UNDEF_RESULT(); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *expr_ptr, new_expr; + SAVE_OPLINE(); + if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && + UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { + expr_ptr = zend_get_bad_ptr(); + if (Z_ISREF_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } else { + ZVAL_MAKE_REF_EX(expr_ptr, 2); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } else { + expr_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_TMP_VAR) { + /* pass */ + } else if (IS_TMP_VAR == IS_CONST) { + Z_TRY_ADDREF_P(expr_ptr); + } else if (IS_TMP_VAR == IS_CV) { + ZVAL_DEREF(expr_ptr); + Z_TRY_ADDREF_P(expr_ptr); + } else /* if (IS_TMP_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(expr_ptr); - HANDLE_EXCEPTION(); + expr_ptr = Z_REFVAL_P(expr_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + ZVAL_COPY_VALUE(&new_expr, expr_ptr); + expr_ptr = &new_expr; + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); } } - if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - if (array_ptr == array_ref) { - ZVAL_NEW_REF(array_ref, array_ref); - array_ptr = Z_REFVAL_P(array_ref); + } + } + + if (IS_TMP_VAR != IS_UNUSED) { + zval *offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + zend_string *str; + zend_ulong hval; + +add_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_TMP_VAR != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index; } - Z_ADDREF_P(array_ref); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); - } else { - array_ptr = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(array_ptr, array_ref); } - if (Z_OBJ_P(array_ptr)->properties - && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(Z_OBJ_P(array_ptr)->properties); - } - Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); +str_index: + zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index: + zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto add_again; + } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { + zval tmp; + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_COPY(&tmp, expr_ptr); } - - properties = Z_OBJPROP_P(array_ptr); - if (zend_hash_num_elements(properties) == 0) { - Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1; - - - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + /* A userland error handler can do funky things to the expression, so reset it */ + zval_ptr_dtor(expr_ptr); + ZVAL_COPY_VALUE(expr_ptr, &tmp); } - - Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); if (UNEXPECTED(EG(exception))) { + zval_ptr_dtor_nogc(expr_ptr); HANDLE_EXCEPTION(); - } else if (is_empty) { - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else { - ZEND_VM_NEXT_OPCODE(); } + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + goto num_index; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); + hval = Z_RES_HANDLE_P(offset); + goto num_index; + } else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else { + zend_illegal_array_offset_access(offset); + zval_ptr_dtor_nogc(expr_ptr); } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } else { - zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(expr_ptr); + } } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_END_SILENCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zval *array; + uint32_t size; USE_OPLINE - if (E_HAS_ONLY_FATAL_ERRORS(EG(error_reporting)) - && !E_HAS_ONLY_FATAL_ERRORS(Z_LVAL_P(EX_VAR(opline->op1.var)))) { - EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var)); + SAVE_OPLINE(); + array = EX_VAR(opline->result.var); + if (IS_TMP_VAR != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_ARR(array, zend_new_array(0)); + ZEND_VM_NEXT_OPCODE(); } - ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - zend_reference *ref = NULL; - bool ret; + zval *container; + bool result; + zend_ulong hval; + zval *offset; SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(value)) { - if (IS_TMP_VAR == IS_VAR) { - ref = Z_REF_P(value); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + zval *value; + zend_string *str; + +isset_dim_obj_array: + ht = Z_ARRVAL_P(container); +isset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_TMP_VAR != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_prop; + } + } + value = zend_hash_find_ex(ht, str, IS_TMP_VAR == IS_CONST); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_prop: + value = zend_hash_index_find(ht, hval); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + offset = Z_REFVAL_P(offset); + goto isset_again; + } else { + value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); + if (UNEXPECTED(EG(exception))) { + result = 0; + goto isset_dim_obj_exit; + } } - value = Z_REFVAL_P(value); - } - ret = i_zend_is_true(value); - - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - - if (ret) { - zval *result = EX_VAR(opline->result.var); + if (!(opline->extended_value & ZEND_ISEMPTY)) { + /* > IS_NULL means not IS_UNDEF and not IS_NULL */ + result = value != NULL && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - ZVAL_COPY_VALUE(result, value); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_TMP_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); - } else if (IS_TMP_VAR == IS_VAR && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); + if (IS_TMP_VAR & (IS_CONST|IS_CV)) { + /* avoid exception check */ + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_SMART_BRANCH(result, 0); } + } else { + result = (value == NULL || !i_zend_is_true(value)); } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + goto isset_dim_obj_exit; + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto isset_dim_obj_array; + } + } + + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; + } + if (!(opline->extended_value & ZEND_ISEMPTY)) { + result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); + } else { + result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); } +isset_dim_obj_exit: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - zend_reference *ref = NULL; + zval *container; + int result; + zval *offset; + zend_string *name, *tmp_name; SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - if (IS_TMP_VAR & IS_VAR) { - ref = Z_REF_P(value); + if (IS_TMP_VAR == IS_CONST || + (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } + } else { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } - value = Z_REFVAL_P(value); } - if (Z_TYPE_P(value) > IS_NULL) { - zval *result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, value); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_TMP_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); - } else if ((IS_TMP_VAR & IS_VAR) && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); - } + if (IS_TMP_VAR == IS_CONST) { + name = Z_STR_P(offset); + } else { + name = zval_try_get_tmp_string(offset, &tmp_name); + if (UNEXPECTED(!name)) { + result = 0; + goto isset_object_finish; } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } - if ((IS_TMP_VAR & IS_VAR) && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); } - ZEND_VM_NEXT_OPCODE(); + +isset_object_finish: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_NULL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val, *result; - val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + zval *key, *subject; + HashTable *ht; + bool result; - if (Z_TYPE_P(val) > IS_NULL) { - do { - if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { - val = Z_REFVAL_P(val); - if (Z_TYPE_P(val) <= IS_NULL) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - break; - } - } - ZEND_VM_NEXT_OPCODE(); - } while (0); - } + SAVE_OPLINE(); - result = EX_VAR(opline->result.var); - uint32_t short_circuiting_type = opline->extended_value & ZEND_SHORT_CIRCUITING_CHAIN_MASK; - if (EXPECTED(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { - ZVAL_NULL(result); - if (IS_TMP_VAR == IS_CV - && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF) - && (opline->extended_value & ZEND_JMP_NULL_BP_VAR_IS) == 0 - ) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + key = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + subject = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: + ht = Z_ARRVAL_P(subject); + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); + } else { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; } } - } else if (short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { - ZVAL_FALSE(result); - } else { - ZEND_ASSERT(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); - ZVAL_TRUE(result); + zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); + result = 0; } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - zval *result = EX_VAR(opline->result.var); - value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + + SAVE_OPLINE(); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - if (IS_TMP_VAR == IS_CV) { - ZVAL_COPY_DEREF(result, value); - } else if (IS_TMP_VAR == IS_VAR) { - if (UNEXPECTED(Z_ISREF_P(value))) { - ZVAL_COPY_VALUE(result, Z_REFVAL_P(value)); - if (UNEXPECTED(Z_DELREF_P(value) == 0)) { - efree_size(Z_REF_P(value), sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); + + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); + + /* Set the new yielded value */ + if (IS_TMP_VAR != IS_UNUSED) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) { + zval *value; + + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + + value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } + } else { + zval *value_ptr = zend_get_bad_ptr(); + + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + do { + if (IS_TMP_VAR == IS_VAR) { + ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION + && !Z_ISREF_P(value_ptr)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + ZVAL_COPY(&generator->value, value_ptr); + break; + } + } + if (Z_ISREF_P(value_ptr)) { + Z_ADDREF_P(value_ptr); + } else { + ZVAL_MAKE_REF_EX(value_ptr, 2); + } + ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); + } while (0); + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); } } else { - ZVAL_COPY_VALUE(result, value); + zval *value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + /* Consts, temporary variables and references need copying */ + if (IS_TMP_VAR == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } else if (IS_TMP_VAR == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + + + } else { + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_TMP_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } + } } } else { - ZVAL_COPY_VALUE(result, value); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) { - Z_ADDREF_P(result); - } + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); + } + + /* Set the new yielded key */ + if (IS_TMP_VAR != IS_UNUSED) { + zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + key = Z_REFVAL_P(key); + } + ZVAL_COPY(&generator->key, key); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); } + } else { + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); } - ZEND_VM_NEXT_OPCODE(); + + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; + } + + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); + + ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *expr; bool result; SAVE_OPLINE(); - op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); +try_instanceof: + if (Z_TYPE_P(expr) == IS_OBJECT) { + zend_class_entry *ce; + if (IS_VAR == IS_CONST) { + ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (EXPECTED(ce)) { + CACHE_PTR(opline->extended_value, ce); + } + } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { + expr = Z_REFVAL_P(expr); + goto try_instanceof; + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + result = 0; + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_STRICT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ZEND_OPCODE_HANDLER_ARGS_EX int type) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *varname; + zval *retval; + zend_string *name, *tmp_name; + HashTable *target_symbol_table; SAVE_OPLINE(); - op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_identical_function(op1, op2); + varname = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + name = zval_try_get_tmp_string(varname, &tmp_name); + if (UNEXPECTED(!name)) { + if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } - ZEND_VM_SMART_BRANCH(result, 1); + target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); + retval = zend_hash_find_ex(target_symbol_table, name, IS_TMP_VAR == IS_CONST); + if (retval == NULL) { + if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { +fetch_this: + zend_fetch_this_var(type OPLINE_CC EXECUTE_DATA_CC); + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + if (type == BP_VAR_W) { + retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); + } else if (type == BP_VAR_IS || type == BP_VAR_UNSET) { + retval = &EG(uninitialized_zval); + } else { + if (IS_TMP_VAR == IS_CV) { + /* Keep name alive in case an error handler tries to free it. */ + zend_string_addref(name); + } + zend_error_unchecked(E_WARNING, "Undefined %svariable $%S", + (opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name); + if (type == BP_VAR_RW && !EG(exception)) { + retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); + } else { + retval = &EG(uninitialized_zval); + } + if (IS_TMP_VAR == IS_CV) { + zend_string_release(name); + } + } + /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ + } else if (Z_TYPE_P(retval) == IS_INDIRECT) { + retval = Z_INDIRECT_P(retval); + if (Z_TYPE_P(retval) == IS_UNDEF) { + if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { + goto fetch_this; + } + if (type == BP_VAR_W) { + ZVAL_NULL(retval); + } else if (type == BP_VAR_IS || type == BP_VAR_UNSET) { + retval = &EG(uninitialized_zval); + } else { + zend_error_unchecked(E_WARNING, "Undefined %svariable $%S", + (opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name); + if (type == BP_VAR_RW && !EG(exception)) { + ZVAL_NULL(retval); + } else { + retval = &EG(uninitialized_zval); + } + } + } + } + + if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } + + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + ZEND_ASSERT(retval != NULL); + if (type == BP_VAR_R || type == BP_VAR_IS) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else { + ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_R_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zval *op1, *op2; - bool result; + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R)); +} - SAVE_OPLINE(); - op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_not_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_W_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W)); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_RW_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW)); +} - ZEND_VM_SMART_BRANCH(result, 1); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + int fetch_type = + (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ? + BP_VAR_W : BP_VAR_R; + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX fetch_type)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_UNSET_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if 0 - USE_OPLINE -#endif + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET)); +} - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - if (IS_CONST == IS_UNUSED) { - ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_IS_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 USE_OPLINE #endif if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - /* Behave like FETCH_OBJ_W */ if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_ADD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_string **rope; - zval *var; - - /* op1 and result are the same */ - rope = (zend_string**)EX_VAR(opline->op1.var); - if (IS_CONST == IS_CONST) { - var = RT_CONSTANT(opline, opline->op2); - rope[opline->extended_value] = Z_STR_P(var); - if (UNEXPECTED(Z_REFCOUNTED_P(var))) { - Z_ADDREF_P(var); + if (IS_UNUSED == IS_UNUSED) { + ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - } else { - var = RT_CONSTANT(opline, opline->op2); - if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { - if (IS_CONST == IS_CV) { - rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); - } else { - rope[opline->extended_value] = Z_STR_P(var); - } - } else { - SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); + if (IS_TMP_VAR & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } } - rope[opline->extended_value] = zval_get_string_func(var); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_END_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zend_string **rope; - zval *var, *ret; - uint32_t i; - - rope = (zend_string**)EX_VAR(opline->op1.var); - if (IS_CONST == IS_CONST) { - var = RT_CONSTANT(opline, opline->op2); - rope[opline->extended_value] = Z_STR_P(var); - if (UNEXPECTED(Z_REFCOUNTED_P(var))) { - Z_ADDREF_P(var); - } + if (IS_TMP_VAR == IS_UNUSED) { + SAVE_OPLINE(); + zend_verify_missing_return_type(EX(func)); + HANDLE_EXCEPTION(); } else { - var = RT_CONSTANT(opline, opline->op2); - if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { - if (IS_CONST == IS_CV) { - rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); - } else { - rope[opline->extended_value] = Z_STR_P(var); - } - } else { - SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); +/* prevents "undefined variable opline" errors */ +#if 0 || (IS_TMP_VAR != IS_UNUSED) + USE_OPLINE + zval *retval_ref, *retval_ptr; + zend_arg_info *ret_info = EX(func)->common.arg_info - 1; + retval_ref = retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + if (IS_TMP_VAR == IS_CONST) { + ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr); + retval_ref = retval_ptr = EX_VAR(opline->result.var); + } else if (IS_TMP_VAR == IS_VAR) { + if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) { + retval_ref = retval_ptr = Z_INDIRECT_P(retval_ptr); } - rope[opline->extended_value] = zval_get_string_func(var); + ZVAL_DEREF(retval_ptr); + } else if (IS_TMP_VAR == IS_CV) { + ZVAL_DEREF(retval_ptr); + } + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + ZEND_VM_NEXT_OPCODE(); + } + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { + SAVE_OPLINE(); + retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); if (UNEXPECTED(EG(exception))) { - for (i = 0; i <= opline->extended_value; i++) { - zend_string_release_ex(rope[i], 0); - } - ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } + if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { + ZEND_VM_NEXT_OPCODE(); + } } - } - size_t len = 0; - uint32_t flags = ZSTR_COPYABLE_CONCAT_PROPERTIES; - for (i = 0; i <= opline->extended_value; i++) { - flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]); - len += ZSTR_LEN(rope[i]); + zend_reference *ref = NULL; + if (UNEXPECTED(retval_ref != retval_ptr)) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + ref = Z_REF_P(retval_ref); + } else { + /* A cast might happen - unwrap the reference if this is a by-value return */ + if (Z_REFCOUNT_P(retval_ref) == 1) { + ZVAL_UNREF(retval_ref); + } else { + Z_DELREF_P(retval_ref); + ZVAL_COPY(retval_ref, retval_ptr); + } + retval_ptr = retval_ref; + } + } + + SAVE_OPLINE(); + if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, 1, 0))) { + zend_verify_return_error(EX(func), retval_ptr); + HANDLE_EXCEPTION(); + } + ZEND_VM_NEXT_OPCODE(); +#endif } - ret = EX_VAR(opline->result.var); - ZVAL_STR(ret, zend_string_alloc(len, 0)); - GC_ADD_FLAGS(Z_STR_P(ret), flags); +} - char *target = Z_STRVAL_P(ret); - for (i = 0; i <= opline->extended_value; i++) { - memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i])); - target += ZSTR_LEN(rope[i]); - zend_string_release_ex(rope[i], 0); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value, *arg; + uint32_t arg_num; + + if (IS_UNUSED == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + arg_num = opline->op2.num; } - *target = '\0'; + if (EXPECTED(0)) { + if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_val_by_ref; + } + } else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { +send_val_by_ref:; + ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg)); + } + value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(arg, value); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { + Z_ADDREF_P(arg); + } + } ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_EX_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *value, *arg; uint32_t arg_num; - if (IS_CONST == IS_CONST) { + if (IS_UNUSED == IS_CONST) { SAVE_OPLINE(); zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); @@ -21257,7 +21622,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_EX_S arg_num = opline->op2.num; } - if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) { + if (EXPECTED(1)) { if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { goto send_val_by_ref; } @@ -21275,7 +21640,7 @@ send_val_by_ref:; ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *expr_ptr, new_expr; @@ -21315,15 +21680,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELE } } - if (IS_CONST != IS_UNUSED) { - zval *offset = RT_CONSTANT(opline, opline->op2); + if (IS_UNUSED != IS_UNUSED) { + zval *offset = NULL; zend_string *str; zend_ulong hval; add_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); - if (IS_CONST != IS_CONST) { + if (IS_UNUSED != IS_CONST) { if (ZEND_HANDLE_NUMERIC(str, hval)) { goto num_index; } @@ -21334,7 +21699,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELE hval = Z_LVAL_P(offset); num_index: zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { offset = Z_REFVAL_P(offset); goto add_again; } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { @@ -21367,7 +21732,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELE zend_use_resource_as_offset(offset); hval = Z_RES_HANDLE_P(offset); goto num_index; - } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); str = ZSTR_EMPTY_ALLOC(); goto str_index; @@ -21386,7 +21751,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELE ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *array; uint32_t size; @@ -21401,14 +21766,104 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SP if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init_mixed(Z_ARRVAL_P(array)); } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { ZVAL_ARR(array, zend_new_array(0)); ZEND_VM_NEXT_OPCODE(); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + bool result; + zval *varname; + zend_string *name, *tmp_name; + HashTable *target_symbol_table; + + SAVE_OPLINE(); + varname = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + + target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); + value = zend_hash_find_ex(target_symbol_table, name, IS_TMP_VAR == IS_CONST); + + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + if (!value) { + result = (opline->extended_value & ZEND_ISEMPTY); + } else { + if (Z_TYPE_P(value) == IS_INDIRECT) { + value = Z_INDIRECT_P(value); + } + if (!(opline->extended_value & ZEND_ISEMPTY)) { + if (Z_ISREF_P(value)) { + value = Z_REFVAL_P(value); + } + result = Z_TYPE_P(value) > IS_NULL; + } else { + result = !i_zend_is_true(value); + } + } + + ZEND_VM_SMART_BRANCH(result, true); +} + +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *expr; + bool result; + + SAVE_OPLINE(); + expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + +try_instanceof: + if (Z_TYPE_P(expr) == IS_OBJECT) { + zend_class_entry *ce; + + if (IS_UNUSED == IS_CONST) { + ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (EXPECTED(ce)) { + CACHE_PTR(opline->extended_value, ce); + } + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { + expr = Z_REFVAL_P(expr); + goto try_instanceof; + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + result = 0; + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -21495,9 +21950,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_TM } /* Set the new yielded key */ - if (IS_CONST != IS_UNUSED) { - zval *key = RT_CONSTANT(opline, opline->op2); - if ((IS_CONST & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + if (IS_UNUSED != IS_UNUSED) { + zval *key = NULL; + if ((IS_UNUSED & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { key = Z_REFVAL_P(key); } ZVAL_COPY(&generator->key, key); @@ -21530,79 +21985,276 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_TM ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COUNT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1; - HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); - zval *result; + zend_long count; + SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_TMP_VAR == IS_CONST); - if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - ZEND_VM_SMART_BRANCH(result, 0); - } - if (opline->extended_value) { - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - ZEND_VM_SMART_BRANCH(result, 0); - } - SAVE_OPLINE(); - if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - result = zend_hash_find(ht, Z_STR_P(op1)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 0); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 0); + while (1) { + if (Z_TYPE_P(op1) == IS_ARRAY) { + count = zend_hash_num_elements(Z_ARRVAL_P(op1)); + break; + } else if (Z_TYPE_P(op1) == IS_OBJECT) { + zend_object *zobj = Z_OBJ_P(op1); + + /* first, we check if the handler is defined */ + if (zobj->handlers->count_elements) { + if (SUCCESS == zobj->handlers->count_elements(zobj, &count)) { + break; + } + if (UNEXPECTED(EG(exception))) { + count = 0; + break; + } + } + + /* if not and the object implements Countable we call its count() method */ + if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) { + zval retval; + + zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT)); + zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval); + count = zval_get_long(&retval); + zval_ptr_dtor(&retval); + break; } + + /* If There's no handler and it doesn't implement Countable then emit a TypeError */ + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + continue; } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - } else if (Z_TYPE_P(op1) <= IS_FALSE) { - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { + count = 0; + zend_type_error("%s(): Argument #1 ($value) must be of type Countable|array, %s given", opline->extended_value ? "sizeof" : "count", zend_zval_value_name(op1)); + break; + } + + ZVAL_LONG(EX_VAR(opline->result.var), count); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_array *ht = Z_ARRVAL_P(_get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC)); + ZVAL_LONG(EX_VAR(opline->result.var), zend_hash_num_elements(ht)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR) && !(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + SAVE_OPLINE(); + zend_array_destroy(ht); + if (EG(exception)) { + HANDLE_EXCEPTION(); + } + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_CLASS_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (IS_TMP_VAR == IS_UNUSED) { + SAVE_OPLINE(); + if (UNEXPECTED(!EX(func)->common.scope)) { + zend_throw_error(NULL, "get_class() without arguments must be called from within a class"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } else { + zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated"); + ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); + if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } + ZEND_VM_NEXT_OPCODE(); } - result = zend_hash_find_known_hash(ht, ZSTR_EMPTY_ALLOC()); - ZEND_VM_SMART_BRANCH(result, 0); } else { - zend_string *key; - zval key_tmp; + zval *op1; - if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - result = zend_hash_find(ht, Z_STR_P(op1)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 0); + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + while (1) { + if (Z_TYPE_P(op1) == IS_OBJECT) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + continue; + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_type_error("get_class(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(op1)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); } + break; } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +} - SAVE_OPLINE(); - ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) { - ZVAL_STR(&key_tmp, key); - if (zend_compare(op1, &key_tmp) == 0) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(1, 1); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_TYPE_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1; + zend_string *type; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + type = zend_zval_get_legacy_type(op1); + if (EXPECTED(type)) { + ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type); + } else { + ZVAL_STRING(EX_VAR(opline->result.var), "unknown type"); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + div_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + pow_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = EX_VAR(opline->op2.var); + + if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + + if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - } ZEND_HASH_FOREACH_END(); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { + zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = ZVAL_UNDEFINED_OP1(); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = ZVAL_UNDEFINED_OP2(); + } + concat_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_STRICT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + result = fast_is_identical_function(op1, op2); + + + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + compare_function(EX_VAR(opline->result.var), op1, op2); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(0, 1); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 USE_OPLINE @@ -21614,14 +22266,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN } ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_CV == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_TMP_VAR & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 USE_OPLINE @@ -21634,11 +22298,149 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUN } ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } -} + if (IS_TMP_VAR == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + zend_string *op1_str, *op2_str, *str; + + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = EX_VAR(opline->op2.var); + if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + + if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + if (IS_TMP_VAR == IS_CONST) { + op1_str = Z_STR_P(op1); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + op1_str = zend_string_copy(Z_STR_P(op1)); + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + op1_str = zval_get_string_func(op1); + } + if (IS_CV == IS_CONST) { + op2_str = Z_STR_P(op2); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + op2_str = zend_string_copy(Z_STR_P(op2)); + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + } + op2_str = zval_get_string_func(op2); + } + do { + if (IS_TMP_VAR != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + zend_string_release_ex(op1_str, 0); + break; + } + } + if (IS_CV != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + zend_string_release_ex(op2_str, 0); + break; + } + } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) + ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR != IS_CONST) { + zend_string_release_ex(op1_str, 0); + } + if (IS_CV != IS_CONST) { + zend_string_release_ex(op2_str, 0); + } + } while (0); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_ADD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_string **rope; @@ -21646,34 +22448,35 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_ADD_SPEC /* op1 and result are the same */ rope = (zend_string**)EX_VAR(opline->op1.var); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { + var = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); rope[opline->extended_value] = Z_STR_P(var); if (UNEXPECTED(Z_REFCOUNTED_P(var))) { Z_ADDREF_P(var); } } else { - var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + var = EX_VAR(opline->op2.var); if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { + if (IS_CV == IS_CV) { rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); } else { rope[opline->extended_value] = Z_STR_P(var); } } else { SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); } rope[opline->extended_value] = zval_get_string_func(var); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } } ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_END_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_string **rope; @@ -21681,27 +22484,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_END_SPEC uint32_t i; rope = (zend_string**)EX_VAR(opline->op1.var); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { + var = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); rope[opline->extended_value] = Z_STR_P(var); if (UNEXPECTED(Z_REFCOUNTED_P(var))) { Z_ADDREF_P(var); } } else { - var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + var = EX_VAR(opline->op2.var); if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { + if (IS_CV == IS_CV) { rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); } else { rope[opline->extended_value] = Z_STR_P(var); } } else { SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); } rope[opline->extended_value] = zval_get_string_func(var); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + if (UNEXPECTED(EG(exception))) { for (i = 0; i <= opline->extended_value; i++) { zend_string_release_ex(rope[i], 0); @@ -21733,7 +22537,219 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_END_SPEC ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + zval *object; + zend_function *fbc; + zend_class_entry *called_scope; + zend_object *obj; + zend_execute_data *call; + uint32_t call_info; + + SAVE_OPLINE(); + + object = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + if (IS_CV != IS_CONST) { + function_name = EX_VAR(opline->op2.var); + } + + if (IS_CV != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Method name must be a string"); + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } while (0); + } + + if (IS_TMP_VAR == IS_UNUSED) { + obj = Z_OBJ_P(object); + } else { + do { + if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + } else { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + if (IS_TMP_VAR & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } + break; + } + } + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + object = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_CV != IS_CONST) { + + + } + HANDLE_EXCEPTION(); + } + } + if (IS_CV == IS_CONST) { + function_name = EX_VAR(opline->op2.var); + } + zend_invalid_method_call(object, function_name); + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } + } while (0); + } + + called_scope = obj->ce; + + if (IS_CV == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else { + zend_object *orig_obj = obj; + + if (IS_CV == IS_CONST) { + function_name = EX_VAR(opline->op2.var); + } + + /* First, locate the function. */ + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); + } + + + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + HANDLE_EXCEPTION(); + } + if (IS_CV == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(obj == orig_obj)) { + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); + } + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + } + + if (IS_CV != IS_CONST) { + + + } + + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; + } else if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR|IS_CV)) { + if (IS_TMP_VAR == IS_CV) { + GC_ADDREF(obj); /* For $this pointer */ + } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; + } + + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, obj); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = EX_VAR(opline->op2.var); + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +case_true: + ZEND_VM_SMART_BRANCH_TRUE(); + } else { +case_false: + ZEND_VM_SMART_BRANCH_FALSE(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto case_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +case_double: + if (d1 == d2) { + goto case_true; + } else { + goto case_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto case_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + + + if (result) { + goto case_true; + } else { + goto case_false; + } + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *expr_ptr, new_expr; @@ -21773,15 +22789,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELE } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_CV != IS_UNUSED) { + zval *offset = EX_VAR(opline->op2.var); zend_string *str; zend_ulong hval; add_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_CV != IS_CONST) { if (ZEND_HANDLE_NUMERIC(str, hval)) { goto num_index; } @@ -21792,7 +22808,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELE hval = Z_LVAL_P(offset); num_index: zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { offset = Z_REFVAL_P(offset); goto add_again; } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { @@ -21825,7 +22841,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELE zend_use_resource_as_offset(offset); hval = Z_RES_HANDLE_P(offset); goto num_index; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); str = ZSTR_EMPTY_ALLOC(); goto str_index; @@ -21833,7 +22849,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELE zend_illegal_array_offset_access(offset); zval_ptr_dtor_nogc(expr_ptr); } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + } else { if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { zend_cannot_add_element(); @@ -21843,7 +22860,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELE ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *array; uint32_t size; @@ -21858,14 +22875,179 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SP if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init_mixed(Z_ARRVAL_P(array)); } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { ZVAL_ARR(array, zend_new_array(0)); ZEND_VM_NEXT_OPCODE(); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + bool result; + zend_ulong hval; + zval *offset; + + SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + offset = EX_VAR(opline->op2.var); + + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + zval *value; + zend_string *str; + +isset_dim_obj_array: + ht = Z_ARRVAL_P(container); +isset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_CV != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_prop; + } + } + value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_prop: + value = zend_hash_index_find(ht, hval); + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + offset = Z_REFVAL_P(offset); + goto isset_again; + } else { + value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); + if (UNEXPECTED(EG(exception))) { + result = 0; + goto isset_dim_obj_exit; + } + } + + if (!(opline->extended_value & ZEND_ISEMPTY)) { + /* > IS_NULL means not IS_UNDEF and not IS_NULL */ + result = value != NULL && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + + if (IS_TMP_VAR & (IS_CONST|IS_CV)) { + /* avoid exception check */ + + + ZEND_VM_SMART_BRANCH(result, 0); + } + } else { + result = (value == NULL || !i_zend_is_true(value)); + } + goto isset_dim_obj_exit; + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto isset_dim_obj_array; + } + } + + if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; + } + if (!(opline->extended_value & ZEND_ISEMPTY)) { + result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); + } else { + result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); + } + +isset_dim_obj_exit: + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + int result; + zval *offset; + zend_string *name, *tmp_name; + + SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + + if (IS_TMP_VAR == IS_CONST || + (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } + } else { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } + } + + if (IS_CV == IS_CONST) { + name = Z_STR_P(offset); + } else { + name = zval_try_get_tmp_string(offset, &tmp_name); + if (UNEXPECTED(!name)) { + result = 0; + goto isset_object_finish; + } + } + + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + +isset_object_finish: + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *key, *subject; + HashTable *ht; + bool result; + + SAVE_OPLINE(); + + key = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + subject = EX_VAR(opline->op2.var); + + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: + ht = Z_ARRVAL_P(subject); + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); + } else { + if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } + } + zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); + result = 0; + } + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -21952,13 +23134,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_TM } /* Set the new yielded key */ - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *key = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + if (IS_CV != IS_UNUSED) { + zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + if ((IS_CV & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { key = Z_REFVAL_P(key); } ZVAL_COPY(&generator->key, key); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (Z_TYPE(generator->key) == IS_LONG && Z_LVAL(generator->key) > generator->largest_used_integer_key @@ -21987,5302 +23169,5647 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_TM ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BIND_LEXICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *closure, *var; - SAVE_OPLINE(); - op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); + closure = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (opline->extended_value & ZEND_BIND_REF) { + /* By-ref binding */ + var = _get_zval_ptr_cv_BP_VAR_W(opline->op2.var EXECUTE_DATA_CC); + if (Z_ISREF_P(var)) { + Z_ADDREF_P(var); + } else { + ZVAL_MAKE_REF_EX(var, 2); + } + } else { + var = EX_VAR(opline->op2.var); + if (UNEXPECTED(Z_ISUNDEF_P(var)) && !(opline->extended_value & ZEND_BIND_IMPLICIT)) { + SAVE_OPLINE(); + var = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + } + ZVAL_DEREF(var); + Z_TRY_ADDREF_P(var); + } + + zend_closure_bind_var_ex(closure, + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT)), var); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_STRICT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_pre_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *var_ptr; + + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); SAVE_OPLINE(); - op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(var_ptr); + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, NULL OPLINE_CC EXECUTE_DATA_CC); + break; + } + } + increment_function(var_ptr); + } while (0); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + } - SAVE_OPLINE(); - op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_STRICT_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_SPEC_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *var_ptr; - SAVE_OPLINE(); - op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_increment_function(var_ptr); + if (UNEXPECTED(0)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); + } + + ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_SPEC_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if 0 USE_OPLINE -#endif + zval *var_ptr; - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - if (IS_UNUSED == IS_UNUSED) { - ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_increment_function(var_ptr); + if (UNEXPECTED(1)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); } - ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_NEXT_OPCODE(); } + + ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_pre_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS) { - if (IS_TMP_VAR == IS_UNUSED) { - SAVE_OPLINE(); - zend_verify_missing_return_type(EX(func)); - HANDLE_EXCEPTION(); - } else { -/* prevents "undefined variable opline" errors */ -#if 0 || (IS_TMP_VAR != IS_UNUSED) - USE_OPLINE - zval *retval_ref, *retval_ptr; - zend_arg_info *ret_info = EX(func)->common.arg_info - 1; - retval_ref = retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + USE_OPLINE + zval *var_ptr; - if (IS_TMP_VAR == IS_CONST) { - ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr); - retval_ref = retval_ptr = EX_VAR(opline->result.var); - } else if (IS_TMP_VAR == IS_VAR) { - if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) { - retval_ref = retval_ptr = Z_INDIRECT_P(retval_ptr); - } - ZVAL_DEREF(retval_ptr); - } else if (IS_TMP_VAR == IS_CV) { - ZVAL_DEREF(retval_ptr); - } + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { - ZEND_VM_NEXT_OPCODE(); - } + SAVE_OPLINE(); + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(var_ptr); + } - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { - SAVE_OPLINE(); - retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { - ZEND_VM_NEXT_OPCODE(); - } - } + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); - zend_reference *ref = NULL; - if (UNEXPECTED(retval_ref != retval_ptr)) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - ref = Z_REF_P(retval_ref); - } else { - /* A cast might happen - unwrap the reference if this is a by-value return */ - if (Z_REFCOUNT_P(retval_ref) == 1) { - ZVAL_UNREF(retval_ref); - } else { - Z_DELREF_P(retval_ref); - ZVAL_COPY(retval_ref, retval_ptr); - } - retval_ptr = retval_ref; + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, NULL OPLINE_CC EXECUTE_DATA_CC); + break; } } + decrement_function(var_ptr); + } while (0); - SAVE_OPLINE(); - if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, 1, 0))) { - zend_verify_return_error(EX(func), retval_ptr); - HANDLE_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); -#endif + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_SPEC_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value, *arg; - uint32_t arg_num; + zval *var_ptr; - if (IS_UNUSED == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - arg_num = opline->op2.num; - } + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(0)) { - if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - goto send_val_by_ref; - } - } else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { -send_val_by_ref:; - ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg)); - } - value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(arg, value); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { - Z_ADDREF_P(arg); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_decrement_function(var_ptr); + if (UNEXPECTED(0)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); } + ZEND_VM_NEXT_OPCODE(); } - ZEND_VM_NEXT_OPCODE(); + + ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAL_EX_SPEC_TMP_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_SPEC_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value, *arg; - uint32_t arg_num; + zval *var_ptr; - if (IS_UNUSED == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - arg_num = opline->op2.num; - } + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(1)) { - if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - goto send_val_by_ref; - } - } else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { -send_val_by_ref:; - ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg)); - } - value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(arg, value); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { - Z_ADDREF_P(arg); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_decrement_function(var_ptr); + if (UNEXPECTED(1)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); } + ZEND_VM_NEXT_OPCODE(); } - ZEND_VM_NEXT_OPCODE(); + + ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_post_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *expr_ptr, new_expr; + zval *var_ptr; - SAVE_OPLINE(); - if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && - UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = zend_get_bad_ptr(); - if (Z_ISREF_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } else { - ZVAL_MAKE_REF_EX(expr_ptr, 2); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } else { - expr_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_TMP_VAR) { - /* pass */ - } else if (IS_TMP_VAR == IS_CONST) { - Z_TRY_ADDREF_P(expr_ptr); - } else if (IS_TMP_VAR == IS_CV) { - ZVAL_DEREF(expr_ptr); - Z_TRY_ADDREF_P(expr_ptr); - } else /* if (IS_TMP_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(expr_ptr); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - ZVAL_COPY_VALUE(&new_expr, expr_ptr); - expr_ptr = &new_expr; - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } - } - } + SAVE_OPLINE(); + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(var_ptr); } - if (IS_UNUSED != IS_UNUSED) { - zval *offset = NULL; - zend_string *str; - zend_ulong hval; + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); -add_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_UNUSED != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index; - } - } -str_index: - zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index: - zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto add_again; - } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { - zval tmp; - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_COPY(&tmp, expr_ptr); - } - zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - /* A userland error handler can do funky things to the expression, so reset it */ - zval_ptr_dtor(expr_ptr); - ZVAL_COPY_VALUE(expr_ptr, &tmp); - } - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(expr_ptr); - HANDLE_EXCEPTION(); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, EX_VAR(opline->result.var) OPLINE_CC EXECUTE_DATA_CC); + break; } - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); - goto num_index; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - zend_use_resource_as_offset(offset); - hval = Z_RES_HANDLE_P(offset); - goto num_index; - } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else { - zend_illegal_array_offset_access(offset); - zval_ptr_dtor_nogc(expr_ptr); } + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + increment_function(var_ptr); + } while (0); - } else { - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { - zend_cannot_add_element(); - zval_ptr_dtor_nogc(expr_ptr); - } - } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zval *array; - uint32_t size; USE_OPLINE + zval *var_ptr; - SAVE_OPLINE(); - array = EX_VAR(opline->result.var); - if (IS_TMP_VAR != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); - } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZVAL_ARR(array, zend_new_array(0)); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + fast_long_increment_function(var_ptr); ZEND_VM_NEXT_OPCODE(); } + + ZEND_VM_TAIL_CALL(zend_post_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_post_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *var_ptr; - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(var_ptr); } - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, EX_VAR(opline->result.var) OPLINE_CC EXECUTE_DATA_CC); + break; + } + } + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - /* Set the new yielded value */ - if (IS_TMP_VAR != IS_UNUSED) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) { - zval *value; + decrement_function(var_ptr); + } while (0); - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } - } else { - zval *value_ptr = zend_get_bad_ptr(); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - do { - if (IS_TMP_VAR == IS_VAR) { - ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION - && !Z_ISREF_P(value_ptr)) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - ZVAL_COPY(&generator->value, value_ptr); - break; - } - } - if (Z_ISREF_P(value_ptr)) { - Z_ADDREF_P(value_ptr); - } else { - ZVAL_MAKE_REF_EX(value_ptr, 2); - } - ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); - } while (0); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } - } else { - zval *value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + fast_long_decrement_function(var_ptr); + ZEND_VM_NEXT_OPCODE(); + } + + ZEND_VM_TAIL_CALL(zend_post_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *retval_ptr; + zval *return_value; + + + SAVE_OPLINE(); + + return_value = EX(return_value); - /* Consts, temporary variables and references need copying */ - if (IS_TMP_VAR == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } else if (IS_TMP_VAR == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + do { + if ((IS_VAR & (IS_CONST|IS_TMP_VAR)) || + (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { + /* Not supposed to happen, but we'll allow it */ + zend_error(E_NOTICE, "Only variable references should be returned by reference"); + retval_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (!return_value) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_TMP_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) { + ZVAL_COPY_VALUE(return_value, retval_ptr); + break; + } + + ZVAL_NEW_REF(return_value, retval_ptr); + if (IS_VAR == IS_CONST) { + Z_TRY_ADDREF_P(retval_ptr); } } + break; } - } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); - } - /* Set the new yielded key */ - if (IS_UNUSED != IS_UNUSED) { - zval *key = NULL; - if ((IS_UNUSED & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { - key = Z_REFVAL_P(key); - } - ZVAL_COPY(&generator->key, key); + retval_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_VAR) { + ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) { + zend_error(E_NOTICE, "Only variable references should be returned by reference"); + if (return_value) { + ZVAL_NEW_REF(return_value, retval_ptr); + } else { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } + break; + } + } - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); + if (return_value) { + if (Z_ISREF_P(retval_ptr)) { + Z_ADDREF_P(retval_ptr); + } else { + ZVAL_MAKE_REF_EX(retval_ptr, 2); + } + ZVAL_REF(return_value, Z_REF_P(retval_ptr)); } - } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); - } - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); - } else { - generator->send_target = NULL; - } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } while (0); - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); - ZEND_VM_RETURN(); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_TYPE_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1; - zend_string *type; - SAVE_OPLINE(); - op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - type = zend_zval_get_legacy_type(op1); - if (EXPECTED(type)) { - ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type); - } else { - ZVAL_STRING(EX_VAR(opline->result.var), "unknown type"); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + // FIXME: Don't create the ref in the first place? + zend_return_unwrap_ref(execute_data, return_value); + + ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_STRICT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GENERATOR_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - + zval *retval; - ZEND_VM_SMART_BRANCH(result, 1); -} + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ -#if 0 - USE_OPLINE -#endif + SAVE_OPLINE(); + retval = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + /* Copy return value into generator->retval */ + if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { + ZVAL_COPY_VALUE(&generator->retval, retval); + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) { + Z_ADDREF(generator->retval); + } } - ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - if (IS_CV == IS_UNUSED) { - ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else if (IS_VAR == IS_CV) { + ZVAL_COPY_DEREF(&generator->retval, retval); + } else /* if (IS_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_refcounted *ref = Z_COUNTED_P(retval); + + retval = Z_REFVAL_P(retval); + ZVAL_COPY_VALUE(&generator->retval, retval); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(retval)) { + Z_ADDREF_P(retval); + } + } else { + ZVAL_COPY_VALUE(&generator->retval, retval); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + + + EG(current_execute_data) = EX(prev_execute_data); + + /* Close the generator to free up resources */ + zend_generator_close(generator, 1); + + /* Pass execution back to handling code */ + ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if 0 USE_OPLINE -#endif + zval *array_ptr, *array_ref; - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - /* Behave like FETCH_OBJ_W */ - if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + SAVE_OPLINE(); + + if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { + array_ref = array_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(array_ref)) { + array_ptr = Z_REFVAL_P(array_ref); } - ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + array_ref = array_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_ADD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_string **rope; - zval *var; - /* op1 and result are the same */ - rope = (zend_string**)EX_VAR(opline->op1.var); - if (IS_CV == IS_CONST) { - var = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - rope[opline->extended_value] = Z_STR_P(var); - if (UNEXPECTED(Z_REFCOUNTED_P(var))) { - Z_ADDREF_P(var); + if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { + if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { + if (array_ptr == array_ref) { + ZVAL_NEW_REF(array_ref, array_ref); + array_ptr = Z_REFVAL_P(array_ref); + } + Z_ADDREF_P(array_ref); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); + } else { + array_ref = EX_VAR(opline->result.var); + ZVAL_NEW_REF(array_ref, array_ptr); + array_ptr = Z_REFVAL_P(array_ref); } - } else { - var = EX_VAR(opline->op2.var); - if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { - if (IS_CV == IS_CV) { - rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); + if (IS_VAR == IS_CONST) { + ZVAL_ARR(array_ptr, zend_array_dup(Z_ARRVAL_P(array_ptr))); + } else { + SEPARATE_ARRAY(array_ptr); + } + Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0); + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE(); + } else if (IS_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { + if (!Z_OBJCE_P(array_ptr)->get_iterator) { + zend_object *zobj = Z_OBJ_P(array_ptr); + HashTable *properties; + if (UNEXPECTED(zend_object_is_lazy(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (UNEXPECTED(EG(exception))) { + UNDEF_RESULT(); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } + } + if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { + if (array_ptr == array_ref) { + ZVAL_NEW_REF(array_ref, array_ref); + array_ptr = Z_REFVAL_P(array_ref); + } + Z_ADDREF_P(array_ref); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); } else { - rope[opline->extended_value] = Z_STR_P(var); + array_ptr = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(array_ptr, array_ref); } - } else { - SAVE_OPLINE(); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); + if (Z_OBJ_P(array_ptr)->properties + && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(Z_OBJ_P(array_ptr)->properties); + } + Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); } - rope[opline->extended_value] = zval_get_string_func(var); + properties = Z_OBJPROP_P(array_ptr); + if (zend_hash_num_elements(properties) == 0) { + Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1; + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + } + Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } else if (is_empty) { + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } else { + ZEND_VM_NEXT_OPCODE(); + } } + } else { + zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } - ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_END_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_string **rope; - zval *var, *ret; - uint32_t i; + zval *array; + zval *value; + uint32_t value_type; + HashTable *fe_ht; + HashPosition pos; + Bucket *p; - rope = (zend_string**)EX_VAR(opline->op1.var); - if (IS_CV == IS_CONST) { - var = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - rope[opline->extended_value] = Z_STR_P(var); - if (UNEXPECTED(Z_REFCOUNTED_P(var))) { - Z_ADDREF_P(var); - } - } else { - var = EX_VAR(opline->op2.var); - if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { - if (IS_CV == IS_CV) { - rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); - } else { - rope[opline->extended_value] = Z_STR_P(var); + array = EX_VAR(opline->op1.var); + SAVE_OPLINE(); + + ZVAL_DEREF(array); + if (EXPECTED(Z_TYPE_P(array) == IS_ARRAY)) { + pos = zend_hash_iterator_pos_ex(Z_FE_ITER_P(EX_VAR(opline->op1.var)), array); + fe_ht = Z_ARRVAL_P(array); + if (HT_IS_PACKED(fe_ht)) { + value = fe_ht->arPacked + pos; + while (1) { + if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { + /* reached end of iteration */ + goto fe_fetch_w_exit; + } + value_type = Z_TYPE_INFO_P(value); + ZEND_ASSERT(value_type != IS_INDIRECT); + if (EXPECTED(value_type != IS_UNDEF)) { + break; + } + pos++; + value++; + } + EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos + 1; + if (RETURN_VALUE_USED(opline)) { + ZVAL_LONG(EX_VAR(opline->result.var), pos); } } else { - SAVE_OPLINE(); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); + p = fe_ht->arData + pos; + while (1) { + if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { + /* reached end of iteration */ + goto fe_fetch_w_exit; + } + pos++; + value = &p->val; + value_type = Z_TYPE_INFO_P(value); + ZEND_ASSERT(value_type != IS_INDIRECT); + if (EXPECTED(value_type != IS_UNDEF)) { + break; + } + p++; } - rope[opline->extended_value] = zval_get_string_func(var); + EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos; + if (RETURN_VALUE_USED(opline)) { + if (!p->key) { + ZVAL_LONG(EX_VAR(opline->result.var), p->h); + } else { + ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); + } + } + } + } else if (EXPECTED(Z_TYPE_P(array) == IS_OBJECT)) { + zend_object_iterator *iter; + if ((iter = zend_iterator_unwrap(array)) == NULL) { + /* plain object */ - if (UNEXPECTED(EG(exception))) { - for (i = 0; i <= opline->extended_value; i++) { - zend_string_release_ex(rope[i], 0); + fe_ht = Z_OBJPROP_P(array); + pos = zend_hash_iterator_pos(Z_FE_ITER_P(EX_VAR(opline->op1.var)), fe_ht); + p = fe_ht->arData + pos; + while (1) { + if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { + /* reached end of iteration */ + goto fe_fetch_w_exit_exc; } - ZVAL_UNDEF(EX_VAR(opline->result.var)); + pos++; + value = &p->val; + value_type = Z_TYPE_INFO_P(value); + if (EXPECTED(value_type != IS_UNDEF)) { + if (UNEXPECTED(value_type == IS_INDIRECT)) { + value = Z_INDIRECT_P(value); + value_type = Z_TYPE_INFO_P(value); + if (EXPECTED(value_type != IS_UNDEF) + && EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key, 0) == SUCCESS)) { + if ((value_type & Z_TYPE_MASK) != IS_REFERENCE) { + zend_property_info *prop_info = + zend_get_property_info_for_slot(Z_OBJ_P(array), value); + if (prop_info) { + if (UNEXPECTED(prop_info->flags & ZEND_ACC_READONLY)) { + zend_throw_error(NULL, + "Cannot acquire reference to readonly property %s::$%s", + ZSTR_VAL(prop_info->ce->name), ZSTR_VAL(p->key)); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + if (ZEND_TYPE_IS_SET(prop_info->type)) { + ZVAL_NEW_REF(value, value); + ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(value), prop_info); + value_type = IS_REFERENCE_EX; + } + } + } + break; + } + } else if (EXPECTED(Z_OBJCE_P(array)->default_properties_count == 0) + || !p->key + || zend_check_property_access(Z_OBJ_P(array), p->key, 1) == SUCCESS) { + break; + } + } + p++; + } + EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos; + if (RETURN_VALUE_USED(opline)) { + if (UNEXPECTED(!p->key)) { + ZVAL_LONG(EX_VAR(opline->result.var), p->h); + } else if (ZSTR_VAL(p->key)[0]) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); + } else { + const char *class_name, *prop_name; + size_t prop_name_len; + zend_unmangle_property_name_ex( + p->key, &class_name, &prop_name, &prop_name_len); + ZVAL_STRINGL(EX_VAR(opline->result.var), prop_name, prop_name_len); + } + } + } else { + const zend_object_iterator_funcs *funcs = iter->funcs; + if (++iter->index > 0) { + /* This could cause an endless loop if index becomes zero again. + * In case that ever happens we need an additional flag. */ + funcs->move_forward(iter); + if (UNEXPECTED(EG(exception) != NULL)) { + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + if (UNEXPECTED(funcs->valid(iter) == FAILURE)) { + /* reached end of iteration */ + if (UNEXPECTED(EG(exception) != NULL)) { + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + goto fe_fetch_w_exit; + } + } + value = funcs->get_current_data(iter); + if (UNEXPECTED(EG(exception) != NULL)) { + UNDEF_RESULT(); HANDLE_EXCEPTION(); } + if (!value) { + /* failure in get_current_data */ + goto fe_fetch_w_exit; + } + if (RETURN_VALUE_USED(opline)) { + if (funcs->get_current_key) { + funcs->get_current_key(iter, EX_VAR(opline->result.var)); + if (UNEXPECTED(EG(exception) != NULL)) { + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + } else { + ZVAL_LONG(EX_VAR(opline->result.var), iter->index); + } + } + value_type = Z_TYPE_INFO_P(value); + } + } else { + zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array)); +fe_fetch_w_exit_exc: + if (UNEXPECTED(EG(exception))) { + UNDEF_RESULT(); + HANDLE_EXCEPTION(); } +fe_fetch_w_exit: + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } - size_t len = 0; - uint32_t flags = ZSTR_COPYABLE_CONCAT_PROPERTIES; - for (i = 0; i <= opline->extended_value; i++) { - flags &= ZSTR_GET_COPYABLE_CONCAT_PROPERTIES(rope[i]); - len += ZSTR_LEN(rope[i]); + if (EXPECTED((value_type & Z_TYPE_MASK) != IS_REFERENCE)) { + zend_refcounted *gc = Z_COUNTED_P(value); + zval *ref; + ZVAL_NEW_EMPTY_REF(value); + ref = Z_REFVAL_P(value); + ZVAL_COPY_VALUE_EX(ref, value, gc, value_type); } - ret = EX_VAR(opline->result.var); - ZVAL_STR(ret, zend_string_alloc(len, 0)); - GC_ADD_FLAGS(Z_STR_P(ret), flags); + if (EXPECTED(opline->op2_type == IS_CV)) { + zval *variable_ptr = EX_VAR(opline->op2.var); + if (EXPECTED(variable_ptr != value)) { + zend_reference *ref; - char *target = Z_STRVAL_P(ret); - for (i = 0; i <= opline->extended_value; i++) { - memcpy(target, ZSTR_VAL(rope[i]), ZSTR_LEN(rope[i])); - target += ZSTR_LEN(rope[i]); - zend_string_release_ex(rope[i], 0); + ref = Z_REF_P(value); + GC_ADDREF(ref); + i_zval_ptr_dtor(variable_ptr); + ZVAL_REF(variable_ptr, ref); + } + } else { + Z_ADDREF_P(value); + ZVAL_REF(EX_VAR(opline->op2.var), Z_REF_P(value)); } - *target = '\0'; - - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *expr_ptr, new_expr; - - SAVE_OPLINE(); - if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && - UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = zend_get_bad_ptr(); - if (Z_ISREF_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } else { - ZVAL_MAKE_REF_EX(expr_ptr, 2); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } else { - expr_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_TMP_VAR) { - /* pass */ - } else if (IS_TMP_VAR == IS_CONST) { - Z_TRY_ADDREF_P(expr_ptr); - } else if (IS_TMP_VAR == IS_CV) { - ZVAL_DEREF(expr_ptr); - Z_TRY_ADDREF_P(expr_ptr); - } else /* if (IS_TMP_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(expr_ptr); + zval *value; + zval *result = EX_VAR(opline->result.var); - expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - ZVAL_COPY_VALUE(&new_expr, expr_ptr); - expr_ptr = &new_expr; - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } - } - } + value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - if (IS_CV != IS_UNUSED) { - zval *offset = EX_VAR(opline->op2.var); - zend_string *str; - zend_ulong hval; - -add_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_CV != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index; - } - } -str_index: - zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index: - zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto add_again; - } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { - zval tmp; - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_COPY(&tmp, expr_ptr); - } - zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - /* A userland error handler can do funky things to the expression, so reset it */ - zval_ptr_dtor(expr_ptr); - ZVAL_COPY_VALUE(expr_ptr, &tmp); - } - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(expr_ptr); - HANDLE_EXCEPTION(); + if (IS_VAR == IS_CV) { + ZVAL_COPY_DEREF(result, value); + } else if (IS_VAR == IS_VAR) { + if (UNEXPECTED(Z_ISREF_P(value))) { + ZVAL_COPY_VALUE(result, Z_REFVAL_P(value)); + if (UNEXPECTED(Z_DELREF_P(value) == 0)) { + efree_size(Z_REF_P(value), sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(result)) { + Z_ADDREF_P(result); } - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); - goto num_index; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - zend_use_resource_as_offset(offset); - hval = Z_RES_HANDLE_P(offset); - goto num_index; - } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - str = ZSTR_EMPTY_ALLOC(); - goto str_index; } else { - zend_illegal_array_offset_access(offset); - zval_ptr_dtor_nogc(expr_ptr); + ZVAL_COPY_VALUE(result, value); } - - } else { - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { - zend_cannot_add_element(); - zval_ptr_dtor_nogc(expr_ptr); + ZVAL_COPY_VALUE(result, value); + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) { + Z_ADDREF_P(result); + } } } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SIMPLE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zval *array; - uint32_t size; USE_OPLINE + zval *varptr, *arg; - SAVE_OPLINE(); - array = EX_VAR(opline->result.var); - if (IS_TMP_VAR != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); - } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZVAL_ARR(array, zend_new_array(0)); - ZEND_VM_NEXT_OPCODE(); + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + + if (IS_VAR == IS_CV) { + ZVAL_COPY(arg, varptr); + } else /* if (IS_VAR == IS_VAR) */ { + ZVAL_COPY_VALUE(arg, varptr); } + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + zval *object; + zval *property; + zval *value; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); - - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = RT_CONSTANT(opline, opline->op2); - /* Set the new yielded value */ - if (IS_TMP_VAR != IS_UNUSED) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) { - zval *value; + do { + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_op_object; + } + if (IS_VAR == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } - value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } +assign_op_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + UNDEF_RESULT(); + break; + } + } + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zval *value_ptr = zend_get_bad_ptr(); + zend_reference *ref; - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ do { - if (IS_TMP_VAR == IS_VAR) { - ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION - && !Z_ISREF_P(value_ptr)) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - ZVAL_COPY(&generator->value, value_ptr); + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + zptr = Z_REFVAL_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); break; } } - if (Z_ISREF_P(value_ptr)) { - Z_ADDREF_P(value_ptr); + + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + if (prop_info) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); } else { - ZVAL_MAKE_REF_EX(value_ptr, 2); + zend_binary_op(zptr, zptr, value OPLINE_CC); } - ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); } while (0); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), zptr); + } } } else { - zval *value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); + } + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); - /* Consts, temporary variables and references need copying */ - if (IS_TMP_VAR == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } else if (IS_TMP_VAR == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + zval *value, *container, *dim; + HashTable *ht; + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +assign_dim_op_array: + SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); +assign_dim_op_new_array: + dim = RT_CONSTANT(opline, opline->op2); + if (IS_CONST == IS_UNUSED) { + var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); + if (UNEXPECTED(!var_ptr)) { + zend_cannot_add_element(); + goto assign_dim_op_ret_null; + } + } else { + if (IS_CONST == IS_CONST) { + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_TMP_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } + var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(!var_ptr)) { + goto assign_dim_op_ret_null; } } - } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); - } - /* Set the new yielded key */ - if (IS_CV != IS_UNUSED) { - zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if ((IS_CV & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { - key = Z_REFVAL_P(key); - } - ZVAL_COPY(&generator->key, key); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); + do { + if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; + } + } + zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); + } while (0); - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); - } - - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); - } else { - generator->send_target = NULL; - } - - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); + if (EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto assign_dim_op_array; + } + } - ZEND_VM_RETURN(); -} + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BIND_LEXICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *closure, *var; + dim = RT_CONSTANT(opline, opline->op2); + if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + uint8_t old_type; - closure = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if (opline->extended_value & ZEND_BIND_REF) { - /* By-ref binding */ - var = _get_zval_ptr_cv_BP_VAR_W(opline->op2.var EXECUTE_DATA_CC); - if (Z_ISREF_P(var)) { - Z_ADDREF_P(var); + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + ht = zend_new_array(8); + old_type = Z_TYPE_P(container); + ZVAL_ARR(container, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_op_ret_null; + } + } + goto assign_dim_op_new_array; } else { - ZVAL_MAKE_REF_EX(var, 2); - } - } else { - var = EX_VAR(opline->op2.var); - if (UNEXPECTED(Z_ISUNDEF_P(var)) && !(opline->extended_value & ZEND_BIND_IMPLICIT)) { - SAVE_OPLINE(); - var = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + dim = RT_CONSTANT(opline, opline->op2); + zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); +assign_dim_op_ret_null: + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); } } - ZVAL_DEREF(var); - Z_TRY_ADDREF_P(var); } - zend_closure_bind_var_ex(closure, - (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT)), var); - ZEND_VM_NEXT_OPCODE(); + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_pre_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *var_ptr; - - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zval *value; SAVE_OPLINE(); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(var_ptr); - } + value = RT_CONSTANT(opline, opline->op2); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); do { if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { zend_reference *ref = Z_REF_P(var_ptr); var_ptr = Z_REFVAL_P(var_ptr); if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_incdec_typed_ref(ref, NULL OPLINE_CC EXECUTE_DATA_CC); + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); break; } } - increment_function(var_ptr); + zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); } while (0); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_SPEC_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = RT_CONSTANT(opline, opline->op2); - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - fast_long_increment_function(var_ptr); - if (UNEXPECTED(0)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + do { + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto pre_incdec_object; + } + if (IS_VAR == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; } - ZEND_VM_NEXT_OPCODE(); - } - ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); +pre_incdec_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + UNDEF_RESULT(); + break; + } + } + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); + zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); + } + } else { + zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); + } + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_SPEC_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - fast_long_increment_function(var_ptr); - if (UNEXPECTED(1)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - } - ZEND_VM_NEXT_OPCODE(); - } - - ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); -} - -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_pre_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - SAVE_OPLINE(); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(var_ptr); - } + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = RT_CONSTANT(opline, opline->op2); do { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto post_incdec_object; + } + if (IS_VAR == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_incdec_typed_ref(ref, NULL OPLINE_CC EXECUTE_DATA_CC); +post_incdec_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); break; } } - decrement_function(var_ptr); + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); + } + } else { + zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); + } + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } } while (0); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_SPEC_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; + zval *container; - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zend_fetch_dimension_address_W(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - fast_long_decrement_function(var_ptr); - if (UNEXPECTED(0)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - } - ZEND_VM_NEXT_OPCODE(); - } - ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_SPEC_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; + zval *container; - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zend_fetch_dimension_address_RW(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - fast_long_decrement_function(var_ptr); - if (UNEXPECTED(1)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - } - ZEND_VM_NEXT_OPCODE(); - } - ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_post_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { +#if 0 USE_OPLINE - zval *var_ptr; - - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - SAVE_OPLINE(); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(var_ptr); - } - - do { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); +#endif - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_incdec_typed_ref(ref, EX_VAR(opline->result.var) OPLINE_CC EXECUTE_DATA_CC); - break; + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if (IS_CONST == IS_UNUSED) { + ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + if (IS_VAR & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } } } - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - - increment_function(var_ptr); - } while (0); - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; + zval *container; - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zend_fetch_dimension_address_UNSET(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - fast_long_increment_function(var_ptr); - ZEND_VM_NEXT_OPCODE(); - } - ZEND_VM_TAIL_CALL(zend_post_inc_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_post_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; - - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zval *property, *container, *result; SAVE_OPLINE(); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(var_ptr); - } - - do { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_incdec_typed_ref(ref, EX_VAR(opline->result.var) OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + zend_fetch_property_address( + result, container, IS_VAR, property, IS_CONST, + ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); - decrement_function(var_ptr); - } while (0); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; + zval *property, *container, *result; - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - fast_long_decrement_function(var_ptr); - ZEND_VM_NEXT_OPCODE(); - } - ZEND_VM_TAIL_CALL(zend_post_dec_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { +#if 0 USE_OPLINE - zval *retval_ptr; - zval *return_value; - - - retval_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - return_value = EX(return_value); - +#endif - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) { - SAVE_OPLINE(); - retval_ptr = ZVAL_UNDEFINED_OP1(); - if (return_value) { - ZVAL_NULL(return_value); - } - } else if (!return_value) { - if (IS_VAR & (IS_VAR|IS_TMP_VAR)) { - if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) { - SAVE_OPLINE(); - rc_dtor_func(Z_COUNTED_P(retval_ptr)); - } + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + /* Behave like FETCH_OBJ_W */ + if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) { - Z_ADDREF_P(return_value); - } - } - } else if (IS_VAR == IS_CV) { - do { - if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { - zend_refcounted *ref = Z_COUNTED_P(retval_ptr); - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (GC_MAY_LEAK(ref)) { - SAVE_OPLINE(); - gc_possible_root(ref); - } - ZVAL_NULL(retval_ptr); - break; - } else { - Z_ADDREF_P(retval_ptr); - } - } else { - retval_ptr = Z_REFVAL_P(retval_ptr); - if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } - } - } - ZVAL_COPY_VALUE(return_value, retval_ptr); - } while (0); - } else /* if (IS_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(retval_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(retval_ptr); - - retval_ptr = Z_REFVAL_P(retval_ptr); - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { + if (IS_VAR == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); + } else { + Z_TRY_ADDREF_P(op1); } - } else { - ZVAL_COPY_VALUE(return_value, retval_ptr); } } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container, *property, *result; + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container, *dim; + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + dim = RT_CONSTANT(opline, opline->op2); - ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_VAR == IS_VAR + && Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT + && UNEXPECTED(!Z_ISREF_P(container)) + ) { + zend_error(E_NOTICE, "Attempting to set reference to non referenceable value"); + zend_fetch_dimension_address_LIST_r(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_fetch_dimension_address_W(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); + } + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *retval_ptr; - zval *return_value; - + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + value = RT_CONSTANT((opline+1), (opline+1)->op1); - return_value = EX(return_value); + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; + } + zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - do { - if ((IS_VAR & (IS_CONST|IS_TMP_VAR)) || - (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { - /* Not supposed to happen, but we'll allow it */ - zend_error(E_NOTICE, "Only variable references should be returned by reference"); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - retval_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (!return_value) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } else { - if (IS_VAR == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) { - ZVAL_COPY_VALUE(return_value, retval_ptr); - break; +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } } - ZVAL_NEW_REF(return_value, retval_ptr); - if (IS_VAR == IS_CONST) { - Z_TRY_ADDREF_P(retval_ptr); + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CONST != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CONST == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CONST == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; } + /* Fall through to write_property for hooks. */ } - break; } + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + } else { + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + if (UNEXPECTED(!name)) { - retval_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_VAR) { - ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) { - zend_error(E_NOTICE, "Only variable references should be returned by reference"); - if (return_value) { - ZVAL_NEW_REF(return_value, retval_ptr); - } else { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } - break; - } + UNDEF_RESULT(); + goto exit_assign_obj; } + } - if (return_value) { - if (Z_ISREF_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } else { - ZVAL_MAKE_REF_EX(retval_ptr, 2); - } - ZVAL_REF(return_value, Z_REF_P(retval_ptr)); - } + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_DEREF(value); + } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } while (0); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } - ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GENERATOR_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *retval; - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - retval = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - /* Copy return value into generator->retval */ - if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { - ZVAL_COPY_VALUE(&generator->retval, retval); - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) { - Z_ADDREF(generator->retval); - } + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; } - } else if (IS_VAR == IS_CV) { - ZVAL_COPY_DEREF(&generator->retval, retval); - } else /* if (IS_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_refcounted *ref = Z_COUNTED_P(retval); + zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } - retval = Z_REFVAL_P(retval); - ZVAL_COPY_VALUE(&generator->retval, retval); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(retval)) { - Z_ADDREF_P(retval); +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_TMP_VAR == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_TMP_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ } - } else { - ZVAL_COPY_VALUE(&generator->retval, retval); + } + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + } else { + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + if (UNEXPECTED(!name)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + goto exit_assign_obj; } } + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_DEREF(value); + } - EG(current_execute_data) = EX(prev_execute_data); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - /* Close the generator to free up resources */ - zend_generator_close(generator, 1); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } - /* Pass execution back to handling code */ - ZEND_VM_RETURN(); +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_USER_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *arg, *param; + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - arg = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - param = ZEND_CALL_VAR(EX(call), opline->result.var); - if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) { - zend_param_must_be_ref(EX(call)->func, opline->op2.num); - Z_TRY_ADDREF_P(arg); - ZVAL_NEW_REF(param, arg); - } else { - ZVAL_COPY(param, arg); + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; + } + zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *expr; - zval *result = EX_VAR(opline->result.var); +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - SAVE_OPLINE(); - expr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - switch (opline->extended_value) { - case IS_LONG: - ZVAL_LONG(result, zval_get_long(expr)); - break; - case IS_DOUBLE: - ZVAL_DOUBLE(result, zval_get_double(expr)); - break; - case IS_STRING: - ZVAL_STR(result, zval_get_string(expr)); - break; - default: - ZEND_ASSERT(opline->extended_value != _IS_BOOL && "Must use ZEND_BOOL instead"); - if (IS_VAR & (IS_VAR|IS_CV)) { - ZVAL_DEREF(expr); - } - /* If value is already of correct type, return it directly */ - if (Z_TYPE_P(expr) == opline->extended_value) { - ZVAL_COPY_VALUE(result, expr); - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - - if (opline->extended_value == IS_ARRAY) { - zend_cast_zval_to_array(result, expr, IS_VAR); + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CV != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CV == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CV == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } } else { - ZEND_ASSERT(opline->extended_value == IS_OBJECT); - zend_cast_zval_to_object(result, expr, IS_VAR); + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ } + } + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + } else { + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + if (UNEXPECTED(!name)) { + + + UNDEF_RESULT(); + goto exit_assign_obj; + } + } + + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_DEREF(value); + } + + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } + + +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *array_ptr, *result; + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); + orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - array_ptr = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { - result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, array_ptr); - if (IS_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(array_ptr); - } - Z_FE_POS_P(result) = 0; - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); - } else if (IS_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { - zend_object *zobj = Z_OBJ_P(array_ptr); - if (!zobj->ce->get_iterator) { - if (UNEXPECTED(zend_object_is_lazy(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (UNEXPECTED(EG(exception))) { - UNDEF_RESULT(); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_CONST == IS_UNUSED) { + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; } } - HashTable *properties = zobj->properties; - if (properties) { - if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(properties); + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_DEREF(value); + } + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_CONST == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } else if (IS_CONST == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); } - properties = zobj->properties = zend_array_dup(properties); + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); } + } + } else { + dim = RT_CONSTANT(opline, opline->op2); + if (IS_CONST == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { - properties = zobj->handlers->get_properties(zobj); + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + value = RT_CONSTANT((opline+1), (opline+1)->op1); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); + } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); - result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, array_ptr); - if (IS_VAR != IS_TMP_VAR) { - Z_ADDREF_P(array_ptr); + GC_ADDREF(obj); + dim = RT_CONSTANT(opline, opline->op2); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; } - if (zend_hash_num_elements(properties) == 0) { - Z_FE_ITER_P(result) = (uint32_t) -1; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_CONST & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); } - Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } else if (is_empty) { - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else { - ZEND_VM_NEXT_OPCODE(); + + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); } - } - } else { - zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); - } -} + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_CONST == IS_UNUSED) { + zend_use_new_element_for_string(); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *array_ptr, *array_ref; - SAVE_OPLINE(); + UNDEF_RESULT(); + } else { + dim = RT_CONSTANT(opline, opline->op2); + value = RT_CONSTANT((opline+1), (opline+1)->op1); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { - array_ref = array_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(array_ref)) { - array_ptr = Z_REFVAL_P(array_ref); - } - } else { - array_ref = array_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - } - if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { - if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { - if (array_ptr == array_ref) { - ZVAL_NEW_REF(array_ref, array_ref); - array_ptr = Z_REFVAL_P(array_ref); } - Z_ADDREF_P(array_ref); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); - } else { - array_ref = EX_VAR(opline->result.var); - ZVAL_NEW_REF(array_ref, array_ptr); - array_ptr = Z_REFVAL_P(array_ref); - } - if (IS_VAR == IS_CONST) { - ZVAL_ARR(array_ptr, zend_array_dup(Z_ARRVAL_P(array_ptr))); - } else { - SEPARATE_ARRAY(array_ptr); - } - Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0); + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = RT_CONSTANT(opline, opline->op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); - } else if (IS_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { - if (!Z_OBJCE_P(array_ptr)->get_iterator) { - zend_object *zobj = Z_OBJ_P(array_ptr); - HashTable *properties; - if (UNEXPECTED(zend_object_is_lazy(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (UNEXPECTED(EG(exception))) { - UNDEF_RESULT(); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } - if (IS_VAR == IS_VAR || IS_VAR == IS_CV) { - if (array_ptr == array_ref) { - ZVAL_NEW_REF(array_ref, array_ref); - array_ptr = Z_REFVAL_P(array_ref); - } - Z_ADDREF_P(array_ref); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); + + UNDEF_RESULT(); } else { - array_ptr = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(array_ptr, array_ref); - } - if (Z_OBJ_P(array_ptr)->properties - && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(Z_OBJ_P(array_ptr)->properties); - } - Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); - } + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); - properties = Z_OBJPROP_P(array_ptr); - if (zend_hash_num_elements(properties) == 0) { - Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + goto try_assign_dim_array; } - - Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } else if (is_empty) { - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } - } else { - zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); - } -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *array; - zval *value; - uint32_t value_type; - HashTable *fe_ht; - HashPosition pos; + zend_use_scalar_as_array(); + dim = RT_CONSTANT(opline, opline->op2); +assign_dim_error: - array = EX_VAR(opline->op1.var); - if (UNEXPECTED(Z_TYPE_P(array) != IS_ARRAY)) { - ZEND_VM_TAIL_CALL(zend_fe_fetch_object_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - fe_ht = Z_ARRVAL_P(array); - pos = Z_FE_POS_P(array); - if (HT_IS_PACKED(fe_ht)) { - value = fe_ht->arPacked + pos; - while (1) { - if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { - /* reached end of iteration */ - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } - value_type = Z_TYPE_INFO_P(value); - ZEND_ASSERT(value_type != IS_INDIRECT); - if (EXPECTED(value_type != IS_UNDEF)) { - break; - } - pos++; - value++; - } - Z_FE_POS_P(array) = pos + 1; - if (RETURN_VALUE_USED(opline)) { - ZVAL_LONG(EX_VAR(opline->result.var), pos); - } - } else { - Bucket *p; - p = fe_ht->arData + pos; - while (1) { - if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { - /* reached end of iteration */ - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } - pos++; - value = &p->val; - value_type = Z_TYPE_INFO_P(value); - ZEND_ASSERT(value_type != IS_INDIRECT); - if (EXPECTED(value_type != IS_UNDEF)) { - break; - } - p++; - } - Z_FE_POS_P(array) = pos; - if (RETURN_VALUE_USED(opline)) { - if (!p->key) { - ZVAL_LONG(EX_VAR(opline->result.var), p->h); - } else { - ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); } } } - if (EXPECTED(opline->op2_type == IS_CV)) { - zval *variable_ptr = EX_VAR(opline->op2.var); - SAVE_OPLINE(); - zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - zval *res = EX_VAR(opline->op2.var); - zend_refcounted *gc = Z_COUNTED_P(value); + if (IS_CONST != IS_UNUSED) { + - ZVAL_COPY_VALUE_EX(res, value, gc, value_type); - if (Z_TYPE_INFO_REFCOUNTED(value_type)) { - GC_ADDREF(gc); - } - ZEND_VM_NEXT_OPCODE(); } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *array; + zval *object_ptr, *orig_object_ptr; zval *value; - uint32_t value_type; - HashTable *fe_ht; - HashPosition pos; - Bucket *p; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; - array = EX_VAR(opline->op1.var); SAVE_OPLINE(); + orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - ZVAL_DEREF(array); - if (EXPECTED(Z_TYPE_P(array) == IS_ARRAY)) { - pos = zend_hash_iterator_pos_ex(Z_FE_ITER_P(EX_VAR(opline->op1.var)), array); - fe_ht = Z_ARRVAL_P(array); - if (HT_IS_PACKED(fe_ht)) { - value = fe_ht->arPacked + pos; - while (1) { - if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { - /* reached end of iteration */ - goto fe_fetch_w_exit; - } - value_type = Z_TYPE_INFO_P(value); - ZEND_ASSERT(value_type != IS_INDIRECT); - if (EXPECTED(value_type != IS_UNDEF)) { - break; - } - pos++; - value++; - } - EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos + 1; - if (RETURN_VALUE_USED(opline)) { - ZVAL_LONG(EX_VAR(opline->result.var), pos); - } - } else { - p = fe_ht->arData + pos; - while (1) { - if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { - /* reached end of iteration */ - goto fe_fetch_w_exit; + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_CONST == IS_UNUSED) { + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); } - pos++; - value = &p->val; - value_type = Z_TYPE_INFO_P(value); - ZEND_ASSERT(value_type != IS_INDIRECT); - if (EXPECTED(value_type != IS_UNDEF)) { - break; + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; } - p++; } - EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos; - if (RETURN_VALUE_USED(opline)) { - if (!p->key) { - ZVAL_LONG(EX_VAR(opline->result.var), p->h); - } else { - ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); - } + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_DEREF(value); } - } - } else if (EXPECTED(Z_TYPE_P(array) == IS_OBJECT)) { - zend_object_iterator *iter; - - if ((iter = zend_iterator_unwrap(array)) == NULL) { - /* plain object */ - - fe_ht = Z_OBJPROP_P(array); - pos = zend_hash_iterator_pos(Z_FE_ITER_P(EX_VAR(opline->op1.var)), fe_ht); - p = fe_ht->arData + pos; - while (1) { - if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { - /* reached end of iteration */ - goto fe_fetch_w_exit_exc; + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_TMP_VAR == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); } - pos++; - value = &p->val; - value_type = Z_TYPE_INFO_P(value); - if (EXPECTED(value_type != IS_UNDEF)) { - if (UNEXPECTED(value_type == IS_INDIRECT)) { - value = Z_INDIRECT_P(value); - value_type = Z_TYPE_INFO_P(value); - if (EXPECTED(value_type != IS_UNDEF) - && EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key, 0) == SUCCESS)) { - if ((value_type & Z_TYPE_MASK) != IS_REFERENCE) { - zend_property_info *prop_info = - zend_get_property_info_for_slot(Z_OBJ_P(array), value); - if (prop_info) { - if (UNEXPECTED(prop_info->flags & ZEND_ACC_READONLY)) { - zend_throw_error(NULL, - "Cannot acquire reference to readonly property %s::$%s", - ZSTR_VAL(prop_info->ce->name), ZSTR_VAL(p->key)); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - if (ZEND_TYPE_IS_SET(prop_info->type)) { - ZVAL_NEW_REF(value, value); - ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(value), prop_info); - value_type = IS_REFERENCE_EX; - } - } - } - break; - } - } else if (EXPECTED(Z_OBJCE_P(array)->default_properties_count == 0) - || !p->key - || zend_check_property_access(Z_OBJ_P(array), p->key, 1) == SUCCESS) { - break; + } else if (IS_TMP_VAR == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); } + zval_ptr_dtor_nogc(free_op_data); } - p++; - } - EG(ht_iterators)[Z_FE_ITER_P(EX_VAR(opline->op1.var))].pos = pos; - if (RETURN_VALUE_USED(opline)) { - if (UNEXPECTED(!p->key)) { - ZVAL_LONG(EX_VAR(opline->result.var), p->h); - } else if (ZSTR_VAL(p->key)[0]) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); - } else { - const char *class_name, *prop_name; - size_t prop_name_len; - zend_unmangle_property_name_ex( - p->key, &class_name, &prop_name, &prop_name_len); - ZVAL_STRINGL(EX_VAR(opline->result.var), prop_name, prop_name_len); + } else if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); } } } else { - const zend_object_iterator_funcs *funcs = iter->funcs; - if (++iter->index > 0) { - /* This could cause an endless loop if index becomes zero again. - * In case that ever happens we need an additional flag. */ - funcs->move_forward(iter); - if (UNEXPECTED(EG(exception) != NULL)) { - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - if (UNEXPECTED(funcs->valid(iter) == FAILURE)) { - /* reached end of iteration */ - if (UNEXPECTED(EG(exception) != NULL)) { - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - goto fe_fetch_w_exit; - } - } - value = funcs->get_current_data(iter); - if (UNEXPECTED(EG(exception) != NULL)) { - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - if (!value) { - /* failure in get_current_data */ - goto fe_fetch_w_exit; + dim = RT_CONSTANT(opline, opline->op2); + if (IS_CONST == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } - if (RETURN_VALUE_USED(opline)) { - if (funcs->get_current_key) { - funcs->get_current_key(iter, EX_VAR(opline->result.var)); - if (UNEXPECTED(EG(exception) != NULL)) { - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - } else { - ZVAL_LONG(EX_VAR(opline->result.var), iter->index); - } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; } - value_type = Z_TYPE_INFO_P(value); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); } - } else { - zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array)); -fe_fetch_w_exit_exc: - if (UNEXPECTED(EG(exception))) { - UNDEF_RESULT(); - HANDLE_EXCEPTION(); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); } -fe_fetch_w_exit: - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } - - if (EXPECTED((value_type & Z_TYPE_MASK) != IS_REFERENCE)) { - zend_refcounted *gc = Z_COUNTED_P(value); - zval *ref; - ZVAL_NEW_EMPTY_REF(value); - ref = Z_REFVAL_P(value); - ZVAL_COPY_VALUE_EX(ref, value, gc, value_type); - } - if (EXPECTED(opline->op2_type == IS_CV)) { - zval *variable_ptr = EX_VAR(opline->op2.var); - if (EXPECTED(variable_ptr != value)) { - zend_reference *ref; - - ref = Z_REF_P(value); - GC_ADDREF(ref); - i_zval_ptr_dtor(variable_ptr); - ZVAL_REF(variable_ptr, ref); + if (garbage) { + GC_DTOR_NO_REF(garbage); } } else { - Z_ADDREF_P(value); - ZVAL_REF(EX_VAR(opline->op2.var), Z_REF_P(value)); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zend_reference *ref = NULL; - bool ret; - - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - ref = Z_REF_P(value); + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } } - value = Z_REFVAL_P(value); - } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); - ret = i_zend_is_true(value); + GC_ADDREF(obj); + dim = RT_CONSTANT(opline, opline->op2); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } - if (ret) { - zval *result = EX_VAR(opline->result.var); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(result, value); - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); - } else if (IS_VAR == IS_VAR && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_CONST == IS_UNUSED) { + zend_use_new_element_for_string(); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + } else { + dim = RT_CONSTANT(opline, opline->op2); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = RT_CONSTANT(opline, opline->op2); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + } else { + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + goto try_assign_dim_array; + } + } else { + zend_use_scalar_as_array(); + dim = RT_CONSTANT(opline, opline->op2); +assign_dim_error: + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); } } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } + if (IS_CONST != IS_UNUSED) { + + } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COALESCE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *object_ptr, *orig_object_ptr; zval *value; - zend_reference *ref = NULL; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - if (IS_VAR & IS_VAR) { - ref = Z_REF_P(value); - } - value = Z_REFVAL_P(value); - } - - if (Z_TYPE_P(value) > IS_NULL) { - zval *result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, value); - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); - } else if ((IS_VAR & IS_VAR) && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_CONST == IS_UNUSED) { + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_DEREF(value); + } + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_CV == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } else if (IS_CV == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } + } else { + dim = RT_CONSTANT(opline, opline->op2); + if (IS_CONST == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; } + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - - if ((IS_VAR & IS_VAR) && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); } - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_NULL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val, *result; + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + GC_ADDREF(obj); + dim = RT_CONSTANT(opline, opline->op2); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } - if (Z_TYPE_P(val) > IS_NULL) { - do { - if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { - val = Z_REFVAL_P(val); - if (Z_TYPE_P(val) <= IS_NULL) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - break; - } + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_CV & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); } - ZEND_VM_NEXT_OPCODE(); - } while (0); - } - result = EX_VAR(opline->result.var); - uint32_t short_circuiting_type = opline->extended_value & ZEND_SHORT_CIRCUITING_CHAIN_MASK; - if (EXPECTED(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { - ZVAL_NULL(result); - if (IS_VAR == IS_CV - && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF) - && (opline->extended_value & ZEND_JMP_NULL_BP_VAR_IS) == 0 - ) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + + + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); } - } - } else if (short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { - ZVAL_FALSE(result); - } else { - ZEND_ASSERT(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); - ZVAL_TRUE(result); - } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_CONST == IS_UNUSED) { + zend_use_new_element_for_string(); - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *result = EX_VAR(opline->result.var); + UNDEF_RESULT(); + } else { + dim = RT_CONSTANT(opline, opline->op2); + value = EX_VAR((opline+1)->op1.var); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - if (IS_VAR == IS_CV) { - ZVAL_COPY_DEREF(result, value); - } else if (IS_VAR == IS_VAR) { - if (UNEXPECTED(Z_ISREF_P(value))) { - ZVAL_COPY_VALUE(result, Z_REFVAL_P(value)); - if (UNEXPECTED(Z_DELREF_P(value) == 0)) { - efree_size(Z_REF_P(value), sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = RT_CONSTANT(opline, opline->op2); + + + UNDEF_RESULT(); + } else { + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + goto try_assign_dim_array; } } else { - ZVAL_COPY_VALUE(result, value); - } - } else { - ZVAL_COPY_VALUE(result, value); - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) { - Z_ADDREF_P(result); + zend_use_scalar_as_array(); + dim = RT_CONSTANT(opline, opline->op2); +assign_dim_error: + + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); } } } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SIMPLE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr, *arg; + if (IS_CONST != IS_UNUSED) { - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - if (IS_VAR == IS_CV) { - ZVAL_COPY(arg, varptr); - } else /* if (IS_VAR == IS_VAR) */ { - ZVAL_COPY_VALUE(arg, varptr); } - - ZEND_VM_NEXT_OPCODE(); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *value; + zval *variable_ptr; SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + value = RT_CONSTANT(opline, opline->op2); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (0 || UNEXPECTED(0)) { + zend_refcounted *garbage = NULL; - ZEND_VM_SMART_BRANCH(result, 1); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES()); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* zend_assign_to_variable() always takes care of op2, never free it! */ + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_STRICT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *value; + zval *variable_ptr; SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_identical_function(op1, op2); - - - ZEND_VM_SMART_BRANCH(result, 1); -} + value = RT_CONSTANT(opline, opline->op2); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + if (0 || UNEXPECTED(1)) { + zend_refcounted *garbage = NULL; - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_not_identical_function(op1, op2); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(1)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES()); + } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object; - zval *property; - zval *value; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; + zval *property, *container, *value_ptr; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); property = RT_CONSTANT(opline, opline->op2); - do { - value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); + value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_op_object; - } - if (IS_VAR == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (1) { + if (IS_VAR == IS_UNUSED) { + if (IS_CONST == IS_CONST) { + zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; - } - -assign_op_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - name = Z_STR_P(property); } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - UNDEF_RESULT(); - break; - } - } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } + if (IS_CONST == IS_CONST) { + zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { - zend_reference *ref; - - do { - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - zptr = Z_REFVAL_P(zptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - if (prop_info) { - /* special case for typed properties */ - zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_binary_op(zptr, zptr, value OPLINE_CC); - } - } while (0); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), zptr); - } + zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } - } else { - zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); - } - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); } - } while (0); + } else { + zend_assign_to_property_reference(container, IS_VAR, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_obj has two opcodes! */ + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; - zval *value, *container, *dim; - HashTable *ht; + zval *property, *container, *value_ptr; SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = RT_CONSTANT(opline, opline->op2); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -assign_dim_op_array: - SEPARATE_ARRAY(container); - ht = Z_ARRVAL_P(container); -assign_dim_op_new_array: - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); - if (UNEXPECTED(!var_ptr)) { - zend_cannot_add_element(); - goto assign_dim_op_ret_null; + value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); + + if (1) { + if (IS_VAR == IS_UNUSED) { + if (IS_CONST == IS_CONST) { + zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } else { if (IS_CONST == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); + zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { - var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(!var_ptr)) { - goto assign_dim_op_ret_null; - } - } - - value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - - do { - if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } + zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } - zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); - } while (0); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); } else { - if (EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto assign_dim_op_array; - } - } + zend_assign_to_property_reference(container, IS_VAR, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(container); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); - } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - uint8_t old_type; - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - ht = zend_new_array(8); - old_type = Z_TYPE_P(container); - ZVAL_ARR(container, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_op_ret_null; - } - } - goto assign_dim_op_new_array; - } else { - dim = RT_CONSTANT(opline, opline->op2); - zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); -assign_dim_op_ret_null: - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; - zval *value; + zval *function_name; + zend_class_entry *ce; + uint32_t call_info; + zend_function *fbc; + zend_execute_data *call; SAVE_OPLINE(); - value = RT_CONSTANT(opline, opline->op2); - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - do { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; + if (IS_VAR == IS_CONST) { + /* no function found. try a static method in class */ + ce = CACHED_PTR(opline->result.num); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + + + HANDLE_EXCEPTION(); + } + if (IS_CONST != IS_CONST) { + CACHE_PTR(opline->result.num, ce); } } - zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); - } while (0); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; + if (IS_VAR == IS_CONST && + IS_CONST == IS_CONST && + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { + /* nothing to do */ + } else if (IS_VAR != IS_CONST && + IS_CONST == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else if (IS_CONST != IS_UNUSED) { + function_name = RT_CONSTANT(opline, opline->op2); + if (IS_CONST != IS_CONST) { + if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if (IS_CONST & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Method name must be a string"); - SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = RT_CONSTANT(opline, opline->op2); - do { - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto pre_incdec_object; - } - if (IS_VAR == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + HANDLE_EXCEPTION(); + } while (0); } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; } -pre_incdec_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - name = Z_STR_P(property); + if (ce->get_static_method) { + fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - UNDEF_RESULT(); - break; - } + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(ce, Z_STR_P(function_name)); } - } else { - zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); - } - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - } while (0); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; + HANDLE_EXCEPTION(); + } + if (IS_CONST == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + if (IS_CONST != IS_CONST) { - SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = RT_CONSTANT(opline, opline->op2); - do { - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto post_incdec_object; - } - if (IS_VAR == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; } + } else { + if (UNEXPECTED(ce->constructor == NULL)) { + zend_throw_error(NULL, "Cannot call constructor"); + HANDLE_EXCEPTION(); + } + if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { + zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); + HANDLE_EXCEPTION(); + } + fbc = ce->constructor; + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + } -post_incdec_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - name = Z_STR_P(property); + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; - } + zend_non_static_method_call(fbc); + HANDLE_EXCEPTION(); } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + /* previous opcode is ZEND_FETCH_CLASS */ + if (IS_VAR == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { + if (Z_TYPE(EX(This)) == IS_OBJECT) { + ce = Z_OBJCE(EX(This)); } else { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); + ce = Z_CE(EX(This)); } - } else { - zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); - } - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); } - } while (0); + call_info = ZEND_CALL_NESTED_FUNCTION; + } + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); + call->prev_execute_data = EX(call); + EX(call) = call; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; + zval *varptr, *arg; - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_W(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); + if (IS_CONST == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + uint32_t arg_num; + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + } + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(arg); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + if (IS_VAR == IS_CV) { + ZVAL_COPY_DEREF(arg, varptr); + } else /* if (IS_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(varptr))) { + zend_refcounted *ref = Z_COUNTED_P(varptr); + + varptr = Z_REFVAL_P(varptr); + ZVAL_COPY_VALUE(arg, varptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(arg)) { + Z_ADDREF_P(arg); + } + } else { + ZVAL_COPY_VALUE(arg, varptr); + } } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_NO_REF_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; + zval *varptr, *arg; - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_RW(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); + if (IS_CONST == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + uint32_t arg_num; + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + } + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(arg, varptr); - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + if (EXPECTED(Z_ISREF_P(varptr))) { + ZEND_VM_NEXT_OPCODE(); } + + SAVE_OPLINE(); + ZVAL_NEW_REF(arg, arg); + zend_error(E_NOTICE, "Only variables should be passed by reference"); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if 0 USE_OPLINE -#endif + zval *varptr, *arg; + uint32_t arg_num; - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_CONST == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - if (IS_CONST == IS_UNUSED) { - ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + arg_num = opline->op2.num; } -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; + if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) { + if (!QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_var; + } - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_UNSET(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(arg, varptr); + if (EXPECTED(Z_ISREF_P(varptr) || + QUICK_ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) { + ZEND_VM_NEXT_OPCODE(); + } + } else { + if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_var; + } - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(arg, varptr); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *property, *container, *result; + if (EXPECTED(Z_ISREF_P(varptr) || + ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) { + ZEND_VM_NEXT_OPCODE(); + } + } SAVE_OPLINE(); + ZVAL_NEW_REF(arg, arg); + zend_error(E_NOTICE, "Only variables should be passed by reference"); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = RT_CONSTANT(opline, opline->op2); - result = EX_VAR(opline->result.var); - zend_fetch_property_address( - result, container, IS_VAR, property, IS_CONST, - ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); - +send_var: + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(Z_ISREF_P(varptr))) { + zend_refcounted *ref = Z_COUNTED_P(varptr); - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + varptr = Z_REFVAL_P(varptr); + ZVAL_COPY_VALUE(arg, varptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(arg)) { + Z_ADDREF_P(arg); + } + } else { + ZVAL_COPY_VALUE(arg, varptr); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_REF_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *property, *container, *result; + zval *varptr, *arg; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = RT_CONSTANT(opline, opline->op2); - result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - + if (IS_CONST == IS_CONST) { + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + uint32_t arg_num; + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + } - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(varptr)) { + Z_ADDREF_P(varptr); + } else { + ZVAL_MAKE_REF_EX(varptr, 2); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZVAL_REF(arg, Z_REF_P(varptr)); + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if 0 USE_OPLINE -#endif + zval *varptr, *arg; + uint32_t arg_num; - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - /* Behave like FETCH_OBJ_W */ - if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_CONST == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + arg_num = opline->op2.num; } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container, *property, *result; - - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = RT_CONSTANT(opline, opline->op2); - result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) { + if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_var_by_ref; + } + } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { +send_var_by_ref: + varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(varptr)) { + Z_ADDREF_P(varptr); + } else { + ZVAL_MAKE_REF_EX(varptr, 2); + } + ZVAL_REF(arg, Z_REF_P(varptr)); - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE(); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container, *dim; + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(arg); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - dim = RT_CONSTANT(opline, opline->op2); + if (IS_VAR == IS_CV) { + ZVAL_COPY_DEREF(arg, varptr); + } else /* if (IS_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(varptr))) { + zend_refcounted *ref = Z_COUNTED_P(varptr); - if (IS_VAR == IS_VAR - && Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT - && UNEXPECTED(!Z_ISREF_P(container)) - ) { - zend_error(E_NOTICE, "Attempting to set reference to non referenceable value"); - zend_fetch_dimension_address_LIST_r(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_fetch_dimension_address_W(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); + varptr = Z_REFVAL_P(varptr); + ZVAL_COPY_VALUE(arg, varptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(arg)) { + Z_ADDREF_P(arg); + } + } else { + ZVAL_COPY_VALUE(arg, varptr); + } } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - value = RT_CONSTANT((opline+1), (opline+1)->op1); + zval *varptr, *arg; - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; + if (IS_CONST == IS_CONST) { + // TODO: Would it make sense to share the cache slot with CHECK_FUNC_ARG? + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + uint32_t arg_num; + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); } - zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); } -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CONST != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CONST == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_CONST == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); - if (UNEXPECTED(!name)) { - - - UNDEF_RESULT(); - goto exit_assign_obj; + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(varptr)) { + Z_ADDREF_P(varptr); + } else { + ZVAL_MAKE_REF_EX(varptr, 2); } - } - - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + ZVAL_REF(arg, Z_REF_P(varptr)); - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE(); } -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(Z_ISREF_P(varptr))) { + zend_refcounted *ref = Z_COUNTED_P(varptr); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); + varptr = Z_REFVAL_P(varptr); + ZVAL_COPY_VALUE(arg, varptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(arg)) { + Z_ADDREF_P(arg); + } + } else { + ZVAL_COPY_VALUE(arg, varptr); } - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_NEXT_OPCODE(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zend_class_entry *ce, *scope; + zend_class_constant *c; + zval *value, *zv, *constant_zv; + zend_string *constant_name; USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; + do { + if (IS_VAR == IS_CONST && IS_CONST == IS_CONST) { + if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); + break; + } } - zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; + if (IS_VAR == IS_CONST) { + if (EXPECTED(CACHED_PTR(opline->extended_value))) { + ce = CACHED_PTR(opline->extended_value); + } else { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } + HANDLE_EXCEPTION(); } + CACHE_PTR(opline->extended_value, ce); + } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_TMP_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_TMP_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_TMP_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ + + HANDLE_EXCEPTION(); } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; + if (IS_VAR != IS_CONST + && IS_CONST == IS_CONST + && EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); + break; } - } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_DEREF(value); - } + constant_zv = RT_CONSTANT(opline, opline->op2); + if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) { + zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + HANDLE_EXCEPTION(); + } + constant_name = Z_STR_P(constant_zv); + /* Magic 'class' for constant OP2 is caught at compile-time */ + if (IS_CONST != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } + ZEND_VM_NEXT_OPCODE(); + } + zv = IS_CONST == IS_CONST + ? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name) + : zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} + if (EXPECTED(zv != NULL)) { + c = Z_PTR_P(zv); + scope = EX(func)->op_array.scope; + if (!zend_verify_const_access(c, scope)) { + zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + HANDLE_EXCEPTION(); + } - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } + if (ce->ce_flags & ZEND_ACC_TRAIT) { + zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + HANDLE_EXCEPTION(); + } -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); + bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; + if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) { + if (c->ce->type == ZEND_USER_CLASS) { + /* Recursion protection only applied to user constants, GH-18463 */ + CONST_PROTECT_RECURSION(c); } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } + zend_deprecated_class_constant(c, constant_name); + if (c->ce->type == ZEND_USER_CLASS) { + CONST_UNPROTECT_RECURSION(c); } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + + + HANDLE_EXCEPTION(); } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; + } + + value = &c->value; + // Enums require loading of all class constants to build the backed enum table + if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { + if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + + + HANDLE_EXCEPTION(); } - /* Fall through to write_property for hooks. */ } - } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } + if (Z_TYPE_P(value) == IS_CONSTANT_AST) { + if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + HANDLE_EXCEPTION(); + } + } + if (IS_CONST == IS_CONST && !is_constant_deprecated) { + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); + } + } else { + zend_throw_error(NULL, "Undefined constant %s::%s", + ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } + HANDLE_EXCEPTION(); + } + } while (0); + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + + ZEND_VM_NEXT_OPCODE(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; + zval *expr_ptr, new_expr; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && + UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { + expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } else { + ZVAL_MAKE_REF_EX(expr_ptr, 2); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } else { + expr_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_TMP_VAR) { + /* pass */ + } else if (IS_VAR == IS_CONST) { + Z_TRY_ADDREF_P(expr_ptr); + } else if (IS_VAR == IS_CV) { + ZVAL_DEREF(expr_ptr); + Z_TRY_ADDREF_P(expr_ptr); + } else /* if (IS_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(expr_ptr); - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; + expr_ptr = Z_REFVAL_P(expr_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + ZVAL_COPY_VALUE(&new_expr, expr_ptr); + expr_ptr = &new_expr; + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } + } } - zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; } -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } + if (IS_CONST != IS_UNUSED) { + zval *offset = RT_CONSTANT(opline, opline->op2); + zend_string *str; + zend_ulong hval; - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CV != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CV == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_CV == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; +add_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_CONST != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index; } - /* Fall through to write_property for hooks. */ } +str_index: + zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index: + zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto add_again; + } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { + zval tmp; + if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { + ZVAL_COPY(&tmp, expr_ptr); + } + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { + /* A userland error handler can do funky things to the expression, so reset it */ + zval_ptr_dtor(expr_ptr); + ZVAL_COPY_VALUE(expr_ptr, &tmp); + } + if (UNEXPECTED(EG(exception))) { + zval_ptr_dtor_nogc(expr_ptr); + HANDLE_EXCEPTION(); + } + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + goto num_index; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); + hval = Z_RES_HANDLE_P(offset); + goto num_index; + } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else { + zend_illegal_array_offset_access(offset); + zval_ptr_dtor_nogc(expr_ptr); } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); - if (UNEXPECTED(!name)) { - UNDEF_RESULT(); - goto exit_assign_obj; + } else { + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(expr_ptr); } } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zval *array; + uint32_t size; + USE_OPLINE -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); + SAVE_OPLINE(); + array = EX_VAR(opline->result.var); + if (IS_VAR != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_ARR(array, zend_new_array(0)); + ZEND_VM_NEXT_OPCODE(); } - - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; + zval *container; + zval *offset; + zend_ulong hval; + zend_string *key; SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + offset = RT_CONSTANT(opline, opline->op2); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_CONST == IS_UNUSED) { - value = RT_CONSTANT((opline+1), (opline+1)->op1); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); + do { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + +unset_dim_array: + SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); +offset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + key = Z_STR_P(offset); + if (IS_CONST != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(key, hval)) { + goto num_index_dim; + } } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); +str_index_dim: + ZEND_ASSERT(ht != &EG(symbol_table)); + zend_hash_del(ht, key); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_dim: + zend_hash_index_del(ht, hval); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto offset_again; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + /* The array may be destroyed while throwing a warning in case the float is not representable as an int. + * Temporarily increase the refcount to detect this situation. */ + GC_TRY_ADDREF(ht); + hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_CONST == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_CONST == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); + break; } - } else if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); + if (EG(exception)) { + break; } - } - } else { - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_NULL) { + key = ZSTR_EMPTY_ALLOC(); + goto str_index_dim; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + key = ZSTR_EMPTY_ALLOC(); + goto str_index_dim; } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + zend_illegal_array_offset_unset(offset); } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; + break; + } else if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto unset_dim_array; } - value = RT_CONSTANT((opline+1), (opline+1)->op1); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + container = ZVAL_UNDEFINED_OP1(); } - if (garbage) { - GC_DTOR_NO_REF(garbage); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + offset = ZVAL_UNDEFINED_OP2(); } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; } + Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset); + } else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { + zend_throw_error(NULL, "Cannot unset string offsets"); + } else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) { + zend_throw_error(NULL, "Cannot unset offset in a non-array variable"); + } else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) { + zend_false_to_array_deprecated(); } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = RT_CONSTANT((opline+1), (opline+1)->op1); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_CONST & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CONST == IS_UNUSED) { - zend_use_new_element_for_string(); - - - UNDEF_RESULT(); - } else { - dim = RT_CONSTANT(opline, opline->op2); - value = RT_CONSTANT((opline+1), (opline+1)->op1); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + } while (0); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = RT_CONSTANT(opline, opline->op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + zval *offset; + zend_string *name, *tmp_name; - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + offset = RT_CONSTANT(opline, opline->op2); - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; + do { + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + if (IS_VAR == IS_CV + && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } + break; } - goto try_assign_dim_array; + } else { + break; } + } + if (IS_CONST == IS_CONST) { + name = Z_STR_P(offset); } else { - zend_use_scalar_as_array(); - dim = RT_CONSTANT(opline, opline->op2); -assign_dim_error: - - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); + name = zval_try_get_tmp_string(offset, &tmp_name); + if (UNEXPECTED(!name)) { + break; } } - } - if (IS_CONST != IS_UNUSED) { + Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); - } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; + + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_CONST == IS_UNUSED) { - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_TMP_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_TMP_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); - GC_ADDREF(obj); - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } + /* Set the new yielded value */ + if (IS_VAR != IS_UNUSED) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_VAR & (IS_CONST|IS_TMP_VAR)) { + zval *value; - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CONST == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = RT_CONSTANT(opline, opline->op2); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = RT_CONSTANT(opline, opline->op2); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); + value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); + zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + do { + if (IS_VAR == IS_VAR) { + ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION + && !Z_ISREF_P(value_ptr)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + ZVAL_COPY(&generator->value, value_ptr); + break; + } } - } - goto try_assign_dim_array; + if (Z_ISREF_P(value_ptr)) { + Z_ADDREF_P(value_ptr); + } else { + ZVAL_MAKE_REF_EX(value_ptr, 2); + } + ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); + } while (0); + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); } } else { - zend_use_scalar_as_array(); - dim = RT_CONSTANT(opline, opline->op2); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); + zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + /* Consts, temporary variables and references need copying */ + if (IS_VAR == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } else if (IS_VAR == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } else { + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } } } + } else { + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); } + + /* Set the new yielded key */ if (IS_CONST != IS_UNUSED) { + zval *key = RT_CONSTANT(opline, opline->op2); + if ((IS_CONST & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + key = Z_REFVAL_P(key); + } + ZVAL_COPY(&generator->key, key); + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); + } + } else { + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; + } + + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); + + ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zend_class_entry *ce, *scope; + zend_class_constant *c; + zval *value, *zv, *constant_zv; + zend_string *constant_name; USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_CONST == IS_UNUSED) { - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } + do { + if (IS_VAR == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); + break; } - } else { - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (IS_VAR == IS_CONST) { + if (EXPECTED(CACHED_PTR(opline->extended_value))) { + ce = CACHED_PTR(opline->extended_value); } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } + CACHE_PTR(opline->extended_value, ce); } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + if (IS_VAR != IS_CONST + && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST + && EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); + break; } - if (garbage) { - GC_DTOR_NO_REF(garbage); + + constant_zv = _get_zval_ptr_tmpvarcv(opline->op2_type, opline->op2, BP_VAR_R EXECUTE_DATA_CC); + if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) { + zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } + constant_name = Z_STR_P(constant_zv); + /* Magic 'class' for constant OP2 is caught at compile-time */ + if ((IS_TMP_VAR|IS_VAR|IS_CV) != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); + FREE_OP(opline->op2_type, opline->op2.var); + ZEND_VM_NEXT_OPCODE(); } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); + zv = (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST + ? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name) + : zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name); - GC_ADDREF(obj); - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; + if (EXPECTED(zv != NULL)) { + c = Z_PTR_P(zv); + scope = EX(func)->op_array.scope; + if (!zend_verify_const_access(c, scope)) { + zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); + if (ce->ce_flags & ZEND_ACC_TRAIT) { + zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); } - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; + if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) { + if (c->ce->type == ZEND_USER_CLASS) { + /* Recursion protection only applied to user constants, GH-18463 */ + CONST_PROTECT_RECURSION(c); + } + zend_deprecated_class_constant(c, constant_name); + if (c->ce->type == ZEND_USER_CLASS) { + CONST_UNPROTECT_RECURSION(c); + } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CONST == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = RT_CONSTANT(opline, opline->op2); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = RT_CONSTANT(opline, opline->op2); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } + value = &c->value; + // Enums require loading of all class constants to build the backed enum table + if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { + if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); } - goto try_assign_dim_array; } - } else { - zend_use_scalar_as_array(); - dim = RT_CONSTANT(opline, opline->op2); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); + if (Z_TYPE_P(value) == IS_CONSTANT_AST) { + if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } + } + if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && !is_constant_deprecated) { + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); } + } else { + zend_throw_error(NULL, "Undefined constant %s::%s", + ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); } - } - if (IS_CONST != IS_UNUSED) { + } while (0); + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + FREE_OP(opline->op2_type, opline->op2.var); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; + zval *object; + zval *property; zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_CONST == IS_UNUSED) { - value = EX_VAR((opline+1)->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_DEREF(value); + do { + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_op_object; } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_CV == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_CV == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } + if (IS_VAR == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } + +assign_op_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_TMP_VAR == IS_CONST) { + name = Z_STR_P(property); } else { - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + UNDEF_RESULT(); + break; } - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + zend_reference *ref; - GC_ADDREF(obj); - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + zptr = Z_REFVAL_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; + } + } - value = EX_VAR((opline+1)->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_CV & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + if (prop_info) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_binary_op(zptr, zptr, value OPLINE_CC); + } + } while (0); - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), zptr); + } + } + } else { + zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); + } + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CONST == IS_UNUSED) { - zend_use_new_element_for_string(); +/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + zval *value, *container, *dim; + HashTable *ht; + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - UNDEF_RESULT(); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +assign_dim_op_array: + SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); +assign_dim_op_new_array: + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_UNUSED) { + var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); + if (UNEXPECTED(!var_ptr)) { + zend_cannot_add_element(); + goto assign_dim_op_ret_null; + } + } else { + if (IS_TMP_VAR == IS_CONST) { + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); } else { - dim = RT_CONSTANT(opline, opline->op2); - value = EX_VAR((opline+1)->op1.var); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(!var_ptr)) { + goto assign_dim_op_ret_null; + } + } + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); + do { + if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; + } } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = RT_CONSTANT(opline, opline->op2); + zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); + } while (0); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + } + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + } else { + if (EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto assign_dim_op_array; + } + } - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + uint8_t old_type; + + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + ht = zend_new_array(8); + old_type = Z_TYPE_P(container); + ZVAL_ARR(container, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_op_ret_null; } - goto try_assign_dim_array; } + goto assign_dim_op_new_array; } else { - zend_use_scalar_as_array(); - dim = RT_CONSTANT(opline, opline->op2); -assign_dim_error: - - + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); +assign_dim_op_ret_null: + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } } - if (IS_CONST != IS_UNUSED) { - - } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *var_ptr; zval *value; - zval *variable_ptr; SAVE_OPLINE(); - value = RT_CONSTANT(opline, opline->op2); - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (0 || UNEXPECTED(0)) { - zend_refcounted *garbage = NULL; + value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(0)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; + } } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES()); + zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); + } while (0); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* zend_assign_to_variable() always takes care of op2, never free it! */ + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - zval *variable_ptr; + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; SAVE_OPLINE(); - value = RT_CONSTANT(opline, opline->op2); - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - if (0 || UNEXPECTED(1)) { - zend_refcounted *garbage = NULL; + do { + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto pre_incdec_object; + } + if (IS_VAR == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(1)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); +pre_incdec_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_TMP_VAR == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + UNDEF_RESULT(); + break; + } } - if (garbage) { - GC_DTOR_NO_REF(garbage); + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); + zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); + } + } else { + zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES()); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* zend_assign_to_variable() always takes care of op2, never free it! */ + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *property, *container, *value_ptr; + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = RT_CONSTANT(opline, opline->op2); - - value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (1) { - if (IS_VAR == IS_UNUSED) { - if (IS_CONST == IS_CONST) { - zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + do { + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto post_incdec_object; + } + if (IS_VAR == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } + +post_incdec_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_TMP_VAR == IS_CONST) { + name = Z_STR_P(property); } else { - if (IS_CONST == IS_CONST) { - zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; + } + } + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + ZVAL_NULL(EX_VAR(opline->result.var)); } else { - zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } + } else { + zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); } - } else { - zend_assign_to_property_reference(container, IS_VAR, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - ZEND_VM_NEXT_OPCODE_EX(1, 2); + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zend_fetch_dimension_address_W(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *property, *container, *value_ptr; + zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = RT_CONSTANT(opline, opline->op2); + zend_fetch_dimension_address_RW(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ +#if 0 + USE_OPLINE +#endif - if (1) { - if (IS_VAR == IS_UNUSED) { - if (IS_CONST == IS_CONST) { - zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } else { - if (IS_CONST == IS_CONST) { - zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - zend_assign_to_property_reference(container, IS_VAR, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_UNUSED) { + ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + if (IS_VAR & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } +} - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zend_fetch_dimension_address_UNSET(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *property, *container, *result; + SAVE_OPLINE(); - ZEND_VM_NEXT_OPCODE_EX(1, 2); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + zend_fetch_property_address( + result, container, IS_VAR, property, IS_TMP_VAR, + ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zend_class_entry *ce; - uint32_t call_info; - zend_function *fbc; - zend_execute_data *call; + zval *property, *container, *result; SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + zend_fetch_property_address(result, container, IS_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - if (IS_VAR == IS_CONST) { - /* no function found. try a static method in class */ - ce = CACHED_PTR(opline->result.num); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ +#if 0 + USE_OPLINE +#endif - HANDLE_EXCEPTION(); - } - if (IS_CONST != IS_CONST) { - CACHE_PTR(opline->result.num, ce); + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + /* Behave like FETCH_OBJ_W */ + if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if (IS_VAR == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } } } - } else if (IS_VAR == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container, *property, *result; - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + zend_fetch_property_address(result, container, IS_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - if (IS_VAR == IS_CONST && - IS_CONST == IS_CONST && - EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { - /* nothing to do */ - } else if (IS_VAR != IS_CONST && - IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else if (IS_CONST != IS_UNUSED) { - function_name = RT_CONSTANT(opline, opline->op2); - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if (IS_CONST & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Method name must be a string"); - +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container, *dim; - HANDLE_EXCEPTION(); - } while (0); - } - } + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - if (ce->get_static_method) { - fbc = ce->get_static_method(ce, Z_STR_P(function_name)); - } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - } - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(ce, Z_STR_P(function_name)); - } + if (IS_VAR == IS_VAR + && Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT + && UNEXPECTED(!Z_ISREF_P(container)) + ) { + zend_error(E_NOTICE, "Attempting to set reference to non referenceable value"); + zend_fetch_dimension_address_LIST_r(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_fetch_dimension_address_W(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - HANDLE_EXCEPTION(); - } - if (IS_CONST == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { - CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - if (IS_CONST != IS_CONST) { +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; } - } else { - if (UNEXPECTED(ce->constructor == NULL)) { - zend_throw_error(NULL, "Cannot call constructor"); - HANDLE_EXCEPTION(); - } - if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { - zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); - HANDLE_EXCEPTION(); - } - fbc = ce->constructor; - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; } - if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { - if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - ce = (zend_class_entry*)Z_OBJ(EX(This)); - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - } else { - zend_non_static_method_call(fbc); - HANDLE_EXCEPTION(); - } - } else { - /* previous opcode is ZEND_FETCH_CLASS */ - if (IS_VAR == IS_UNUSED - && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { - if (Z_TYPE(EX(This)) == IS_OBJECT) { - ce = Z_OBJCE(EX(This)); +assign_object: + zobj = Z_OBJ_P(object); + if (IS_TMP_VAR == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CONST != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CONST == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CONST == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } } else { - ce = Z_CE(EX(This)); + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ } } - call_info = ZEND_CALL_NESTED_FUNCTION; - } - - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, ce); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); -} + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + } else { + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr, *arg; - if (IS_CONST == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - uint32_t arg_num; - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); + UNDEF_RESULT(); + goto exit_assign_obj; } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); } - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(arg); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_DEREF(value); } - if (IS_VAR == IS_CV) { - ZVAL_COPY_DEREF(arg, varptr); - } else /* if (IS_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(varptr))) { - zend_refcounted *ref = Z_COUNTED_P(varptr); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - varptr = Z_REFVAL_P(varptr); - ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); - } - } else { - ZVAL_COPY_VALUE(arg, varptr); - } + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_NO_REF_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr, *arg; - - if (IS_CONST == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - uint32_t arg_num; - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); } - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(arg, varptr); - if (EXPECTED(Z_ISREF_P(varptr))) { - ZEND_VM_NEXT_OPCODE(); +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); } - - SAVE_OPLINE(); - ZVAL_NEW_REF(arg, arg); - zend_error(E_NOTICE, "Only variables should be passed by reference"); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *varptr, *arg; - uint32_t arg_num; + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; - if (IS_CONST == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - arg_num = opline->op2.num; + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; } - if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) { - if (!QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - goto send_var; - } +assign_object: + zobj = Z_OBJ_P(object); + if (IS_TMP_VAR == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(arg, varptr); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (EXPECTED(Z_ISREF_P(varptr) || - QUICK_ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) { - ZEND_VM_NEXT_OPCODE(); +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_TMP_VAR == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_TMP_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ + } } + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - goto send_var; - } - - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(arg, varptr); - - if (EXPECTED(Z_ISREF_P(varptr) || - ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) { - ZEND_VM_NEXT_OPCODE(); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + goto exit_assign_obj; } } - SAVE_OPLINE(); - ZVAL_NEW_REF(arg, arg); - zend_error(E_NOTICE, "Only variables should be passed by reference"); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - -send_var: - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(Z_ISREF_P(varptr))) { - zend_refcounted *ref = Z_COUNTED_P(varptr); - - varptr = Z_REFVAL_P(varptr); - ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); - } - } else { - ZVAL_COPY_VALUE(arg, varptr); + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_DEREF(value); } - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_REF_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr, *arg; + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - SAVE_OPLINE(); - if (IS_CONST == IS_CONST) { - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - uint32_t arg_num; - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); } - varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(varptr)) { - Z_ADDREF_P(varptr); - } else { - ZVAL_MAKE_REF_EX(varptr, 2); +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); } - ZVAL_REF(arg, Z_REF_P(varptr)); - + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *varptr, *arg; - uint32_t arg_num; + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; - if (IS_CONST == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - arg_num = opline->op2.num; - } + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) { - if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - goto send_var_by_ref; - } - } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { -send_var_by_ref: - varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(varptr)) { - Z_ADDREF_P(varptr); - } else { - ZVAL_MAKE_REF_EX(varptr, 2); + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; } - ZVAL_REF(arg, Z_REF_P(varptr)); - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; } - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(arg); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } +assign_object: + zobj = Z_OBJ_P(object); + if (IS_TMP_VAR == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - if (IS_VAR == IS_CV) { - ZVAL_COPY_DEREF(arg, varptr); - } else /* if (IS_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(varptr))) { - zend_refcounted *ref = Z_COUNTED_P(varptr); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - varptr = Z_REFVAL_P(varptr); - ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CV != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CV == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CV == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ } - } else { - ZVAL_COPY_VALUE(arg, varptr); } - } - - ZEND_VM_NEXT_OPCODE(); -} + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + } else { + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr, *arg; - if (IS_CONST == IS_CONST) { - // TODO: Would it make sense to share the cache slot with CHECK_FUNC_ARG? - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - uint32_t arg_num; - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); + UNDEF_RESULT(); + goto exit_assign_obj; } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); } - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(varptr)) { - Z_ADDREF_P(varptr); - } else { - ZVAL_MAKE_REF_EX(varptr, 2); - } - ZVAL_REF(arg, Z_REF_P(varptr)); - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_DEREF(value); } - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if (UNEXPECTED(Z_ISREF_P(varptr))) { - zend_refcounted *ref = Z_COUNTED_P(varptr); + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } - varptr = Z_REFVAL_P(varptr); - ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); - } - } else { - ZVAL_COPY_VALUE(arg, varptr); +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); } - ZEND_VM_NEXT_OPCODE(); + +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zend_class_entry *ce, *scope; - zend_class_constant *c; - zval *value, *zv, *constant_zv; - zend_string *constant_name; USE_OPLINE + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); + orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - do { - if (IS_VAR == IS_CONST && IS_CONST == IS_CONST) { - if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) { - value = CACHED_PTR(opline->extended_value + sizeof(void*)); - break; - } - } - if (IS_VAR == IS_CONST) { - if (EXPECTED(CACHED_PTR(opline->extended_value))) { - ce = CACHED_PTR(opline->extended_value); - } else { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - - - HANDLE_EXCEPTION(); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_TMP_VAR == IS_UNUSED) { + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; } - CACHE_PTR(opline->extended_value, ce); } - } else if (IS_VAR == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - - - HANDLE_EXCEPTION(); + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_DEREF(value); + } + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_CONST == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } else if (IS_CONST == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } } } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + value = RT_CONSTANT((opline+1), (opline+1)->op1); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); } - if (IS_VAR != IS_CONST - && IS_CONST == IS_CONST - && EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { - value = CACHED_PTR(opline->extended_value + sizeof(void*)); - break; + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); } - - constant_zv = RT_CONSTANT(opline, opline->op2); - if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) { - zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - - - HANDLE_EXCEPTION(); + if (garbage) { + GC_DTOR_NO_REF(garbage); } - constant_name = Z_STR_P(constant_zv); - /* Magic 'class' for constant OP2 is caught at compile-time */ - if (IS_CONST != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); - - - ZEND_VM_NEXT_OPCODE(); + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } } - zv = IS_CONST == IS_CONST - ? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name) - : zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name); - - if (EXPECTED(zv != NULL)) { - c = Z_PTR_P(zv); - scope = EX(func)->op_array.scope; - if (!zend_verify_const_access(c, scope)) { - zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } - HANDLE_EXCEPTION(); + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_CONST & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); } - if (ce->ce_flags & ZEND_ACC_TRAIT) { - zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - HANDLE_EXCEPTION(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_TMP_VAR == IS_UNUSED) { + zend_use_new_element_for_string(); - bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; - if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) { - if (c->ce->type == ZEND_USER_CLASS) { - /* Recursion protection only applied to user constants, GH-18463 */ - CONST_PROTECT_RECURSION(c); - } - zend_deprecated_class_constant(c, constant_name); - if (c->ce->type == ZEND_USER_CLASS) { - CONST_UNPROTECT_RECURSION(c); - } - if (EG(exception)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); + UNDEF_RESULT(); + } else { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + value = RT_CONSTANT((opline+1), (opline+1)->op1); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - HANDLE_EXCEPTION(); - } } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - value = &c->value; - // Enums require loading of all class constants to build the backed enum table - if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { - if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - - - HANDLE_EXCEPTION(); - } - } - if (Z_TYPE_P(value) == IS_CONSTANT_AST) { - if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); + UNDEF_RESULT(); + } else { + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); - HANDLE_EXCEPTION(); + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } } - } - if (IS_CONST == IS_CONST && !is_constant_deprecated) { - CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); + goto try_assign_dim_array; } } else { - zend_throw_error(NULL, "Undefined constant %s::%s", - ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); + zend_use_scalar_as_array(); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); +assign_dim_error: - HANDLE_EXCEPTION(); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } - } while (0); - - ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); - - - ZEND_VM_NEXT_OPCODE(); + } + if (IS_TMP_VAR != IS_UNUSED) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *expr_ptr, new_expr; + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && - UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } else { - ZVAL_MAKE_REF_EX(expr_ptr, 2); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } else { - expr_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_TMP_VAR) { - /* pass */ - } else if (IS_VAR == IS_CONST) { - Z_TRY_ADDREF_P(expr_ptr); - } else if (IS_VAR == IS_CV) { - ZVAL_DEREF(expr_ptr); - Z_TRY_ADDREF_P(expr_ptr); - } else /* if (IS_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(expr_ptr); + orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - ZVAL_COPY_VALUE(&new_expr, expr_ptr); - expr_ptr = &new_expr; - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_TMP_VAR == IS_UNUSED) { + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; } } - } - } - - if (IS_CONST != IS_UNUSED) { - zval *offset = RT_CONSTANT(opline, opline->op2); - zend_string *str; - zend_ulong hval; - -add_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_CONST != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index; + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_DEREF(value); + } + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_TMP_VAR == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } else if (IS_TMP_VAR == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); } } -str_index: - zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index: - zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto add_again; - } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { - zval tmp; - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_COPY(&tmp, expr_ptr); + } else { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } - zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - /* A userland error handler can do funky things to the expression, so reset it */ - zval_ptr_dtor(expr_ptr); - ZVAL_COPY_VALUE(expr_ptr, &tmp); + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; } - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(expr_ptr); - HANDLE_EXCEPTION(); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; } - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); - goto num_index; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - zend_use_resource_as_offset(offset); - hval = Z_RES_HANDLE_P(offset); - goto num_index; - } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else { - zend_illegal_array_offset_access(offset); - zval_ptr_dtor_nogc(expr_ptr); } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } - } else { - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { - zend_cannot_add_element(); - zval_ptr_dtor_nogc(expr_ptr); - } - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zval *array; - uint32_t size; - USE_OPLINE + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - SAVE_OPLINE(); - array = EX_VAR(opline->result.var); - if (IS_VAR != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_TMP_VAR == IS_UNUSED) { + zend_use_new_element_for_string(); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + } else { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + } else { + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + goto try_assign_dim_array; + } + } else { + zend_use_scalar_as_array(); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); +assign_dim_error: + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZVAL_ARR(array, zend_new_array(0)); - ZEND_VM_NEXT_OPCODE(); } + if (IS_TMP_VAR != IS_UNUSED) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - zval *offset; - zend_ulong hval; - zend_string *key; + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = RT_CONSTANT(opline, opline->op2); - - do { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; + orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); -unset_dim_array: - SEPARATE_ARRAY(container); - ht = Z_ARRVAL_P(container); -offset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - key = Z_STR_P(offset); - if (IS_CONST != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(key, hval)) { - goto num_index_dim; - } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_TMP_VAR == IS_UNUSED) { + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); } -str_index_dim: - ZEND_ASSERT(ht != &EG(symbol_table)); - zend_hash_del(ht, key); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_dim: - zend_hash_index_del(ht, hval); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto offset_again; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - /* The array may be destroyed while throwing a warning in case the float is not representable as an int. - * Temporarily increase the refcount to detect this situation. */ - GC_TRY_ADDREF(ht); - hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { zend_array_destroy(ht); - break; + goto assign_dim_error; } - if (EG(exception)) { - break; + } + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_DEREF(value); + } + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_CV == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); } - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_NULL) { - key = ZSTR_EMPTY_ALLOC(); - goto str_index_dim; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - zend_use_resource_as_offset(offset); - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - key = ZSTR_EMPTY_ALLOC(); - goto str_index_dim; + } else if (IS_CV == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } + } else { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { - zend_illegal_array_offset_unset(offset); + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } - break; - } else if (Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto unset_dim_array; + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; } + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); } - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - container = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { - offset = ZVAL_UNDEFINED_OP2(); + if (garbage) { + GC_DTOR_NO_REF(garbage); } - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; } - Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset); - } else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - } else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) { - zend_throw_error(NULL, "Cannot unset offset in a non-array variable"); - } else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) { - zend_false_to_array_deprecated(); } - } while (0); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_CV & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - zval *offset; - zend_string *name, *tmp_name; + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = RT_CONSTANT(opline, opline->op2); - do { - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - if (Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (Z_TYPE_P(container) != IS_OBJECT) { - if (IS_VAR == IS_CV - && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_TMP_VAR == IS_UNUSED) { + zend_use_new_element_for_string(); + + + UNDEF_RESULT(); + } else { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + value = EX_VAR((opline+1)->op1.var); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + + + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + + UNDEF_RESULT(); + } else { + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; } - break; } - } else { - break; + goto try_assign_dim_array; } - } - if (IS_CONST == IS_CONST) { - name = Z_STR_P(offset); } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - break; + zend_use_scalar_as_array(); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); +assign_dim_error: + + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); } } - Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - } while (0); + } + if (IS_TMP_VAR != IS_UNUSED) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + zval *variable_ptr; + + SAVE_OPLINE(); + value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (0 || UNEXPECTED(0)) { + zend_refcounted *garbage = NULL; + value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES()); + } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* zend_assign_to_variable() always takes care of op2, never free it! */ + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + zval *value; + zval *variable_ptr; SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } + value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); + if (0 || UNEXPECTED(1)) { + zend_refcounted *garbage = NULL; - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(1)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES()); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* zend_assign_to_variable() always takes care of op2, never free it! */ - /* Set the new yielded value */ - if (IS_VAR != IS_UNUSED) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_VAR & (IS_CONST|IS_TMP_VAR)) { - zval *value; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *property, *container, *value_ptr; - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } - } else { - zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + SAVE_OPLINE(); - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - do { - if (IS_VAR == IS_VAR) { - ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION - && !Z_ISREF_P(value_ptr)) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - ZVAL_COPY(&generator->value, value_ptr); - break; - } - } - if (Z_ISREF_P(value_ptr)) { - Z_ADDREF_P(value_ptr); - } else { - ZVAL_MAKE_REF_EX(value_ptr, 2); - } - ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); - } while (0); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + + if (1) { + if (IS_VAR == IS_UNUSED) { + if (IS_TMP_VAR == IS_CONST) { + zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } else { - zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - /* Consts, temporary variables and references need copying */ - if (IS_VAR == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } else if (IS_VAR == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (IS_TMP_VAR == IS_CONST) { + zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } + zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); + zend_assign_to_property_reference(container, IS_VAR, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); } - /* Set the new yielded key */ - if (IS_CONST != IS_UNUSED) { - zval *key = RT_CONSTANT(opline, opline->op2); - if ((IS_CONST & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { - key = Z_REFVAL_P(key); - } - ZVAL_COPY(&generator->key, key); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *property, *container, *value_ptr; - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); + SAVE_OPLINE(); + + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); + + if (1) { + if (IS_VAR == IS_UNUSED) { + if (IS_TMP_VAR == IS_CONST) { + zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } + } else { + if (IS_TMP_VAR == IS_CONST) { + zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } } } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); + zend_assign_to_property_reference(container, IS_VAR, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); } - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); - } else { - generator->send_target = NULL; - } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); - ZEND_VM_RETURN(); + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1; - HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); - zval *result; + zval *function_name; + zend_class_entry *ce; + uint32_t call_info; + zend_function *fbc; + zend_execute_data *call; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_VAR == IS_CONST); - if (IS_VAR & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); + SAVE_OPLINE(); + + if (IS_VAR == IS_CONST) { + /* no function found. try a static method in class */ + ce = CACHED_PTR(opline->result.num); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); + } + if (IS_TMP_VAR != IS_CONST) { + CACHE_PTR(opline->result.num, ce); + } } - ZEND_VM_SMART_BRANCH(result, 0); + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (opline->extended_value) { - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - ZEND_VM_SMART_BRANCH(result, 0); - } - SAVE_OPLINE(); - if ((IS_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - result = zend_hash_find(ht, Z_STR_P(op1)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 0); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 0); + if (IS_VAR == IS_CONST && + IS_TMP_VAR == IS_CONST && + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { + /* nothing to do */ + } else if (IS_VAR != IS_CONST && + IS_TMP_VAR == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else if (IS_TMP_VAR != IS_UNUSED) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR != IS_CONST) { + if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if (IS_TMP_VAR & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Method name must be a string"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); + } while (0); } - } else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); } - } else if (Z_TYPE_P(op1) <= IS_FALSE) { - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + + if (ce->get_static_method) { + fbc = ce->get_static_method(ce, Z_STR_P(function_name)); + } else { + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + } + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(ce, Z_STR_P(function_name)); } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); + } + if (IS_TMP_VAR == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + if (IS_TMP_VAR != IS_CONST) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } - result = zend_hash_find_known_hash(ht, ZSTR_EMPTY_ALLOC()); - ZEND_VM_SMART_BRANCH(result, 0); } else { - zend_string *key; - zval key_tmp; - - if ((IS_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - result = zend_hash_find(ht, Z_STR_P(op1)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 0); - } + if (UNEXPECTED(ce->constructor == NULL)) { + zend_throw_error(NULL, "Cannot call constructor"); + HANDLE_EXCEPTION(); + } + if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { + zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); + HANDLE_EXCEPTION(); + } + fbc = ce->constructor; + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); } + } - SAVE_OPLINE(); - ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) { - ZVAL_STR(&key_tmp, key); - if (zend_compare(op1, &key_tmp) == 0) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(1, 1); + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + } else { + zend_non_static_method_call(fbc); + HANDLE_EXCEPTION(); + } + } else { + /* previous opcode is ZEND_FETCH_CLASS */ + if (IS_VAR == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { + if (Z_TYPE(EX(This)) == IS_OBJECT) { + ce = Z_OBJCE(EX(This)); + } else { + ce = Z_CE(EX(This)); } - } ZEND_HASH_FOREACH_END(); + } + call_info = ZEND_CALL_NESTED_FUNCTION; } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(0, 1); + + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zend_class_entry *ce, *scope; - zend_class_constant *c; - zval *value, *zv, *constant_zv; - zend_string *constant_name; USE_OPLINE + zval *expr_ptr, new_expr; SAVE_OPLINE(); + if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && + UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { + expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } else { + ZVAL_MAKE_REF_EX(expr_ptr, 2); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } else { + expr_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_TMP_VAR) { + /* pass */ + } else if (IS_VAR == IS_CONST) { + Z_TRY_ADDREF_P(expr_ptr); + } else if (IS_VAR == IS_CV) { + ZVAL_DEREF(expr_ptr); + Z_TRY_ADDREF_P(expr_ptr); + } else /* if (IS_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(expr_ptr); - do { - if (IS_VAR == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) { - value = CACHED_PTR(opline->extended_value + sizeof(void*)); - break; + expr_ptr = Z_REFVAL_P(expr_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + ZVAL_COPY_VALUE(&new_expr, expr_ptr); + expr_ptr = &new_expr; + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } } } - if (IS_VAR == IS_CONST) { - if (EXPECTED(CACHED_PTR(opline->extended_value))) { - ce = CACHED_PTR(opline->extended_value); - } else { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); + } + + if (IS_TMP_VAR != IS_UNUSED) { + zval *offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + zend_string *str; + zend_ulong hval; + +add_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_TMP_VAR != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index; } - CACHE_PTR(opline->extended_value, ce); } - } else if (IS_VAR == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); +str_index: + zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index: + zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto add_again; + } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { + zval tmp; + if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { + ZVAL_COPY(&tmp, expr_ptr); + } + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { + /* A userland error handler can do funky things to the expression, so reset it */ + zval_ptr_dtor(expr_ptr); + ZVAL_COPY_VALUE(expr_ptr, &tmp); + } + if (UNEXPECTED(EG(exception))) { + zval_ptr_dtor_nogc(expr_ptr); HANDLE_EXCEPTION(); } + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + goto num_index; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); + hval = Z_RES_HANDLE_P(offset); + goto num_index; + } else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + str = ZSTR_EMPTY_ALLOC(); + goto str_index; } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); + zend_illegal_array_offset_access(offset); + zval_ptr_dtor_nogc(expr_ptr); } - if (IS_VAR != IS_CONST - && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST - && EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { - value = CACHED_PTR(opline->extended_value + sizeof(void*)); - break; + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } else { + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(expr_ptr); } + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - constant_zv = _get_zval_ptr_tmpvarcv(opline->op2_type, opline->op2, BP_VAR_R EXECUTE_DATA_CC); - if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) { - zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } - constant_name = Z_STR_P(constant_zv); - /* Magic 'class' for constant OP2 is caught at compile-time */ - if ((IS_TMP_VAR|IS_VAR|IS_CV) != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); - FREE_OP(opline->op2_type, opline->op2.var); - ZEND_VM_NEXT_OPCODE(); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zval *array; + uint32_t size; + USE_OPLINE + + SAVE_OPLINE(); + array = EX_VAR(opline->result.var); + if (IS_VAR != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); } - zv = (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST - ? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name) - : zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name); + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_ARR(array, zend_new_array(0)); + ZEND_VM_NEXT_OPCODE(); + } +} - if (EXPECTED(zv != NULL)) { - c = Z_PTR_P(zv); - scope = EX(func)->op_array.scope; - if (!zend_verify_const_access(c, scope)) { - zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + zval *offset; + zend_ulong hval; + zend_string *key; - if (ce->ce_flags & ZEND_ACC_TRAIT) { - zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; - if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) { - if (c->ce->type == ZEND_USER_CLASS) { - /* Recursion protection only applied to user constants, GH-18463 */ - CONST_PROTECT_RECURSION(c); + do { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + +unset_dim_array: + SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); +offset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + key = Z_STR_P(offset); + if (IS_TMP_VAR != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(key, hval)) { + goto num_index_dim; + } } - zend_deprecated_class_constant(c, constant_name); - if (c->ce->type == ZEND_USER_CLASS) { - CONST_UNPROTECT_RECURSION(c); +str_index_dim: + ZEND_ASSERT(ht != &EG(symbol_table)); + zend_hash_del(ht, key); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_dim: + zend_hash_index_del(ht, hval); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto offset_again; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + /* The array may be destroyed while throwing a warning in case the float is not representable as an int. + * Temporarily increase the refcount to detect this situation. */ + GC_TRY_ADDREF(ht); + hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + break; } - if (EG(exception)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } - } - - value = &c->value; - // Enums require loading of all class constants to build the backed enum table - if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { - if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); + break; } + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_NULL) { + key = ZSTR_EMPTY_ALLOC(); + goto str_index_dim; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + } else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + key = ZSTR_EMPTY_ALLOC(); + goto str_index_dim; + } else { + zend_illegal_array_offset_unset(offset); } - if (Z_TYPE_P(value) == IS_CONSTANT_AST) { - if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } + break; + } else if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto unset_dim_array; } - if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && !is_constant_deprecated) { - CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); + } + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + container = ZVAL_UNDEFINED_OP1(); + } + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + offset = ZVAL_UNDEFINED_OP2(); + } + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; } - } else { - zend_throw_error(NULL, "Undefined constant %s::%s", - ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); + Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset); + } else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { + zend_throw_error(NULL, "Cannot unset string offsets"); + } else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) { + zend_throw_error(NULL, "Cannot unset offset in a non-array variable"); + } else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) { + zend_false_to_array_deprecated(); } } while (0); - ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); - - FREE_OP(opline->op2_type, opline->op2.var); - ZEND_VM_NEXT_OPCODE(); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object; - zval *property; - zval *value; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; + zval *container; + zval *offset; zend_string *name, *tmp_name; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); do { - value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_op_object; - } - if (IS_VAR == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + if (IS_VAR == IS_CV + && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + break; + } + } else { + break; } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; } - -assign_op_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(property); + if (IS_TMP_VAR == IS_CONST) { + name = Z_STR_P(offset); } else { - name = zval_try_get_tmp_string(property, &tmp_name); + name = zval_try_get_tmp_string(offset, &tmp_name); if (UNEXPECTED(!name)) { - UNDEF_RESULT(); break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - zend_reference *ref; + Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); - do { - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - zptr = Z_REFVAL_P(zptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } - } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - if (prop_info) { - /* special case for typed properties */ - zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + + SAVE_OPLINE(); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); + + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); + + /* Set the new yielded value */ + if (IS_VAR != IS_UNUSED) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_VAR & (IS_CONST|IS_TMP_VAR)) { + zval *value; + + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + + value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } + } else { + zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + do { + if (IS_VAR == IS_VAR) { + ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION + && !Z_ISREF_P(value_ptr)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + ZVAL_COPY(&generator->value, value_ptr); + break; + } + } + if (Z_ISREF_P(value_ptr)) { + Z_ADDREF_P(value_ptr); } else { - zend_binary_op(zptr, zptr, value OPLINE_CC); + ZVAL_MAKE_REF_EX(value_ptr, 2); } + ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); } while (0); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), zptr); - } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); } } else { - zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); + zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + /* Consts, temporary variables and references need copying */ + if (IS_VAR == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } else if (IS_VAR == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } else { + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } + } } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); + } else { + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); + } + + /* Set the new yielded key */ + if (IS_TMP_VAR != IS_UNUSED) { + zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + key = Z_REFVAL_P(key); } - } while (0); + ZVAL_COPY(&generator->key, key); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); + } + } else { + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); + } + + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; + } + + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); + + ZEND_VM_RETURN(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *variable_ptr; + zval *value_ptr; + zend_refcounted *garbage = NULL; + + SAVE_OPLINE(); + value_ptr = _get_zval_ptr_ptr_var(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + if (IS_VAR == IS_VAR && + UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) { + + zend_throw_error(NULL, "Cannot assign by reference to an array dimension of an object"); + variable_ptr = &EG(uninitialized_zval); + } else if (IS_VAR == IS_VAR && + opline->extended_value == ZEND_RETURNS_FUNCTION && + UNEXPECTED(!Z_ISREF_P(value_ptr))) { + + variable_ptr = zend_wrong_assign_to_variable_reference( + variable_ptr, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_variable_reference(variable_ptr, value_ptr, &garbage); + } + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr); + } + + if (garbage) { + GC_DTOR(garbage); + } - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *var_ptr; @@ -27297,15 +28824,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP SEPARATE_ARRAY(container); ht = Z_ARRVAL_P(container); assign_dim_op_new_array: - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + dim = NULL; + if (IS_UNUSED == IS_UNUSED) { var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { zend_cannot_add_element(); goto assign_dim_op_ret_null; } } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_UNUSED == IS_CONST) { var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); } else { var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); @@ -27318,7 +28845,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); do { - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { zend_reference *ref = Z_REF_P(var_ptr); var_ptr = Z_REFVAL_P(var_ptr); if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { @@ -27344,8 +28871,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(container); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim = NULL; + if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); @@ -27368,7 +28895,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP } goto assign_dim_op_new_array; } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = NULL; zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); assign_dim_op_ret_null: FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -27378,201 +28905,44 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP } } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - zval *value; - - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - do { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); - } while (0); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - } - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; - - SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - do { - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto pre_incdec_object; - } - if (IS_VAR == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; - } - -pre_incdec_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - UNDEF_RESULT(); - break; - } - } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); - } - } else { - zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - } while (0); - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; - - SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - do { - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto post_incdec_object; - } - if (IS_VAR == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; - } - -post_incdec_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; - } - } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); - } - } else { - zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - } while (0); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_W(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zend_fetch_dimension_address_W(container, NULL, IS_UNUSED OPLINE_CC EXECUTE_DATA_CC); + + if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_RW(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zend_fetch_dimension_address_RW(container, NULL, IS_UNUSED OPLINE_CC EXECUTE_DATA_CC); + + if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 USE_OPLINE @@ -27582,857 +28952,451 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_UNUSED == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_VAR & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_UNSET(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *property, *container, *result; + orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - SAVE_OPLINE(); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_UNUSED == IS_UNUSED) { + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_DEREF(value); + } + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_CONST == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } else if (IS_CONST == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } + } else { + dim = NULL; + if (IS_UNUSED == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + value = RT_CONSTANT((opline+1), (opline+1)->op1); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); + } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address( - result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), - (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + GC_ADDREF(obj); + dim = NULL; + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *property, *container, *result; + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_CONST & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ -#if 0 - USE_OPLINE -#endif - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - /* Behave like FETCH_OBJ_W */ - if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } -} + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_UNUSED == IS_UNUSED) { + zend_use_new_element_for_string(); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container, *property, *result; - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + UNDEF_RESULT(); + } else { + dim = NULL; + value = RT_CONSTANT((opline+1), (opline+1)->op1); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container, *dim; - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = NULL; - if (IS_VAR == IS_VAR - && Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT - && UNEXPECTED(!Z_ISREF_P(container)) - ) { - zend_error(E_NOTICE, "Attempting to set reference to non referenceable value"); - zend_fetch_dimension_address_LIST_r(container, dim, (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_fetch_dimension_address_W(container, dim, (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + UNDEF_RESULT(); + } else { + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + goto try_assign_dim_array; + } + } else { + zend_use_scalar_as_array(); + dim = NULL; +assign_dim_error: - SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - value = RT_CONSTANT((opline+1), (opline+1)->op1); - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; } + if (IS_UNUSED != IS_UNUSED) { -assign_object: - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; + + SAVE_OPLINE(); + orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_UNUSED == IS_UNUSED) { + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); + } + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_DEREF(value); + } + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_TMP_VAR == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; + } else if (IS_TMP_VAR == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); } + zval_ptr_dtor_nogc(free_op_data); } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CONST != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CONST == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_CONST == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; + } else if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); } + } + } else { + dim = NULL; + if (IS_UNUSED == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; } + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - - - UNDEF_RESULT(); - goto exit_assign_obj; + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } } - } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_DEREF(value); - } + GC_ADDREF(obj); + dim = NULL; + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_UNUSED == IS_UNUSED) { + zend_use_new_element_for_string(); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + } else { + dim = NULL; + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = NULL; + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + } else { + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + goto try_assign_dim_array; + } + } else { + zend_use_scalar_as_array(); + dim = NULL; +assign_dim_error: + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } } + if (IS_UNUSED != IS_UNUSED) { -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_obj has two opcodes! */ + /* assign_dim has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; zend_refcounted *garbage = NULL; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_UNUSED == IS_UNUSED) { + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); + } + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_DEREF(value); + } + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_CV == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; + } else if (IS_CV == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); } + zval_ptr_dtor_nogc(free_op_data); } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_TMP_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_TMP_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_TMP_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; + } else if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); } + } + } else { + dim = NULL; + if (IS_UNUSED == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); + } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } } - } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_DEREF(value); - } + GC_ADDREF(obj); + dim = NULL; + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_CV & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_UNUSED == IS_UNUSED) { + zend_use_new_element_for_string(); - SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CV != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CV == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_CV == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - - - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - - -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - value = RT_CONSTANT((opline+1), (opline+1)->op1); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_CONST == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_CONST == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = RT_CONSTANT((opline+1), (opline+1)->op1); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = RT_CONSTANT((opline+1), (opline+1)->op1); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_CONST & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_use_new_element_for_string(); - - - UNDEF_RESULT(); - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = RT_CONSTANT((opline+1), (opline+1)->op1); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + UNDEF_RESULT(); + } else { + dim = NULL; + value = EX_VAR((opline+1)->op1.var); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); } @@ -28440,7 +29404,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = NULL; UNDEF_RESULT(); @@ -28461,7 +29425,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP } } else { zend_use_scalar_as_array(); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = NULL; assign_dim_error: @@ -28470,630 +29434,97 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP } } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_UNUSED != IS_UNUSED) { + + } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); /* assign_dim has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; + zval *function_name; + zend_class_entry *ce; + uint32_t call_info; + zend_function *fbc; + zend_execute_data *call; SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_TMP_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_TMP_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + if (IS_VAR == IS_CONST) { + /* no function found. try a static method in class */ + ce = CACHED_PTR(opline->result.num); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + + + HANDLE_EXCEPTION(); } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; + if (IS_UNUSED != IS_CONST) { + CACHE_PTR(opline->result.num, ce); } - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); } - if (garbage) { - GC_DTOR_NO_REF(garbage); + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + + + HANDLE_EXCEPTION(); } } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + + if (IS_VAR == IS_CONST && + IS_UNUSED == IS_CONST && + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { + /* nothing to do */ + } else if (IS_VAR != IS_CONST && + IS_UNUSED == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else if (IS_UNUSED != IS_UNUSED) { + function_name = NULL; + if (IS_UNUSED != IS_CONST) { + if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if (IS_UNUSED & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Method name must be a string"); + + + HANDLE_EXCEPTION(); + } while (0); } } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; + if (ce->get_static_method) { + fbc = ce->get_static_method(ce, Z_STR_P(function_name)); + } else { + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + } + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(ce, Z_STR_P(function_name)); } - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - value = EX_VAR((opline+1)->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_CV == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_CV == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = EX_VAR((opline+1)->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_CV & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_use_new_element_for_string(); - - - UNDEF_RESULT(); - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = EX_VAR((opline+1)->op1.var); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - - - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); -assign_dim_error: - - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *property, *container, *value_ptr; - - SAVE_OPLINE(); - - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (1) { - if (IS_VAR == IS_UNUSED) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } - } else { - zend_assign_to_property_reference(container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *property, *container, *value_ptr; - - SAVE_OPLINE(); - - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); - - if (1) { - if (IS_VAR == IS_UNUSED) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } - } else { - zend_assign_to_property_reference(container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *function_name; - zend_class_entry *ce; - uint32_t call_info; - zend_function *fbc; - zend_execute_data *call; - - SAVE_OPLINE(); - - if (IS_VAR == IS_CONST) { - /* no function found. try a static method in class */ - ce = CACHED_PTR(opline->result.num); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - CACHE_PTR(opline->result.num, ce); - } - } - } else if (IS_VAR == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - - if (IS_VAR == IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { - /* nothing to do */ - } else if (IS_VAR != IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Method name must be a string"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } while (0); - } - } - - if (ce->get_static_method) { - fbc = ce->get_static_method(ce, Z_STR_P(function_name)); - } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - } - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(ce, Z_STR_P(function_name)); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_UNUSED == IS_CONST && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); @@ -29101,8 +29532,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_UNUSED != IS_CONST) { + + } } else { if (UNEXPECTED(ce->constructor == NULL)) { @@ -29149,5381 +29581,5172 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zval *expr_ptr, new_expr; - - SAVE_OPLINE(); - if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && - UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } else { - ZVAL_MAKE_REF_EX(expr_ptr, 2); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (IS_VAR == IS_UNUSED) { + SAVE_OPLINE(); + zend_verify_missing_return_type(EX(func)); + HANDLE_EXCEPTION(); } else { - expr_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_TMP_VAR) { - /* pass */ - } else if (IS_VAR == IS_CONST) { - Z_TRY_ADDREF_P(expr_ptr); - } else if (IS_VAR == IS_CV) { - ZVAL_DEREF(expr_ptr); - Z_TRY_ADDREF_P(expr_ptr); - } else /* if (IS_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(expr_ptr); +/* prevents "undefined variable opline" errors */ +#if 0 || (IS_VAR != IS_UNUSED) + USE_OPLINE + zval *retval_ref, *retval_ptr; + zend_arg_info *ret_info = EX(func)->common.arg_info - 1; + retval_ref = retval_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - ZVAL_COPY_VALUE(&new_expr, expr_ptr); - expr_ptr = &new_expr; - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + if (IS_VAR == IS_CONST) { + ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr); + retval_ref = retval_ptr = EX_VAR(opline->result.var); + } else if (IS_VAR == IS_VAR) { + if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) { + retval_ref = retval_ptr = Z_INDIRECT_P(retval_ptr); } + ZVAL_DEREF(retval_ptr); + } else if (IS_VAR == IS_CV) { + ZVAL_DEREF(retval_ptr); } - } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - zend_string *str; - zend_ulong hval; + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + ZEND_VM_NEXT_OPCODE(); + } -add_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index; - } - } -str_index: - zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index: - zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto add_again; - } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { - zval tmp; - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_COPY(&tmp, expr_ptr); - } - zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - /* A userland error handler can do funky things to the expression, so reset it */ - zval_ptr_dtor(expr_ptr); - ZVAL_COPY_VALUE(expr_ptr, &tmp); - } + if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { + SAVE_OPLINE(); + retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(expr_ptr); HANDLE_EXCEPTION(); } - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); - goto num_index; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - zend_use_resource_as_offset(offset); - hval = Z_RES_HANDLE_P(offset); - goto num_index; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else { - zend_illegal_array_offset_access(offset); - zval_ptr_dtor_nogc(expr_ptr); + if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { + ZEND_VM_NEXT_OPCODE(); + } } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } else { - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { - zend_cannot_add_element(); - zval_ptr_dtor_nogc(expr_ptr); + + zend_reference *ref = NULL; + if (UNEXPECTED(retval_ref != retval_ptr)) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + ref = Z_REF_P(retval_ref); + } else { + /* A cast might happen - unwrap the reference if this is a by-value return */ + if (Z_REFCOUNT_P(retval_ref) == 1) { + ZVAL_UNREF(retval_ref); + } else { + Z_DELREF_P(retval_ref); + ZVAL_COPY(retval_ref, retval_ptr); + } + retval_ptr = retval_ref; + } } + + SAVE_OPLINE(); + if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, 1, 0))) { + zend_verify_return_error(EX(func), retval_ptr); + HANDLE_EXCEPTION(); + } + ZEND_VM_NEXT_OPCODE(); +#endif } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zval *array; - uint32_t size; USE_OPLINE + zval *varptr, *arg; - SAVE_OPLINE(); - array = EX_VAR(opline->result.var); - if (IS_VAR != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + if (IS_UNUSED == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + uint32_t arg_num; + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZVAL_ARR(array, zend_new_array(0)); - ZEND_VM_NEXT_OPCODE(); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - zval *offset; - zend_ulong hval; - zend_string *key; - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(arg); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } - do { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; + if (IS_VAR == IS_CV) { + ZVAL_COPY_DEREF(arg, varptr); + } else /* if (IS_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(varptr))) { + zend_refcounted *ref = Z_COUNTED_P(varptr); -unset_dim_array: - SEPARATE_ARRAY(container); - ht = Z_ARRVAL_P(container); -offset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - key = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(key, hval)) { - goto num_index_dim; - } - } -str_index_dim: - ZEND_ASSERT(ht != &EG(symbol_table)); - zend_hash_del(ht, key); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_dim: - zend_hash_index_del(ht, hval); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto offset_again; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - /* The array may be destroyed while throwing a warning in case the float is not representable as an int. - * Temporarily increase the refcount to detect this situation. */ - GC_TRY_ADDREF(ht); - hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - break; - } - if (EG(exception)) { - break; - } - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_NULL) { - key = ZSTR_EMPTY_ALLOC(); - goto str_index_dim; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - zend_use_resource_as_offset(offset); - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - key = ZSTR_EMPTY_ALLOC(); - goto str_index_dim; - } else { - zend_illegal_array_offset_unset(offset); - } - break; - } else if (Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto unset_dim_array; - } - } - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - container = ZVAL_UNDEFINED_OP1(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { - offset = ZVAL_UNDEFINED_OP2(); - } - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; + varptr = Z_REFVAL_P(varptr); + ZVAL_COPY_VALUE(arg, varptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(arg)) { + Z_ADDREF_P(arg); } - Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset); - } else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - } else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) { - zend_throw_error(NULL, "Cannot unset offset in a non-array variable"); - } else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) { - zend_false_to_array_deprecated(); + } else { + ZVAL_COPY_VALUE(arg, varptr); } - } while (0); + } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - zval *offset; - zend_string *name, *tmp_name; - - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + zval *varptr, *arg; - do { - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - if (Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (Z_TYPE_P(container) != IS_OBJECT) { - if (IS_VAR == IS_CV - && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - break; - } - } else { - break; - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(offset); - } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - break; - } - } - Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); + if (IS_UNUSED == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + uint32_t arg_num; + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); } - } while (0); + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(arg, varptr); + + if (EXPECTED(Z_ISREF_P(varptr))) { + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + ZVAL_NEW_REF(arg, arg); + zend_error(E_NOTICE, "Only variables should be passed by reference"); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *varptr, *arg; + uint32_t arg_num; - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - - SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_UNUSED == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + arg_num = opline->op2.num; } - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); + if (EXPECTED(0)) { + if (!QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_var; + } - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(arg, varptr); - /* Set the new yielded value */ - if (IS_VAR != IS_UNUSED) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_VAR & (IS_CONST|IS_TMP_VAR)) { - zval *value; + if (EXPECTED(Z_ISREF_P(varptr) || + QUICK_ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) { + ZEND_VM_NEXT_OPCODE(); + } + } else { + if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_var; + } - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(arg, varptr); - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } - } else { - zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (EXPECTED(Z_ISREF_P(varptr) || + ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) { + ZEND_VM_NEXT_OPCODE(); + } + } - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - do { - if (IS_VAR == IS_VAR) { - ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION - && !Z_ISREF_P(value_ptr)) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - ZVAL_COPY(&generator->value, value_ptr); - break; - } - } - if (Z_ISREF_P(value_ptr)) { - Z_ADDREF_P(value_ptr); - } else { - ZVAL_MAKE_REF_EX(value_ptr, 2); - } - ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); - } while (0); + SAVE_OPLINE(); + ZVAL_NEW_REF(arg, arg); + zend_error(E_NOTICE, "Only variables should be passed by reference"); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } - } else { - zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); +send_var: + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(Z_ISREF_P(varptr))) { + zend_refcounted *ref = Z_COUNTED_P(varptr); - /* Consts, temporary variables and references need copying */ - if (IS_VAR == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } else if (IS_VAR == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } - } + varptr = Z_REFVAL_P(varptr); + ZVAL_COPY_VALUE(arg, varptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(arg)) { + Z_ADDREF_P(arg); } } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); + ZVAL_COPY_VALUE(arg, varptr); } + ZEND_VM_NEXT_OPCODE(); +} - /* Set the new yielded key */ - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *key = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { - key = Z_REFVAL_P(key); - } - ZVAL_COPY(&generator->key, key); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varptr, *arg; + uint32_t arg_num; - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); + if (IS_UNUSED == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); } } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + arg_num = opline->op2.num; } - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); + if (EXPECTED(1)) { + if (!QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_var; + } + + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(arg, varptr); + + if (EXPECTED(Z_ISREF_P(varptr) || + QUICK_ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) { + ZEND_VM_NEXT_OPCODE(); + } } else { - generator->send_target = NULL; + if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_var; + } + + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(arg, varptr); + + if (EXPECTED(Z_ISREF_P(varptr) || + ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) { + ZEND_VM_NEXT_OPCODE(); + } } - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); + ZVAL_NEW_REF(arg, arg); + zend_error(E_NOTICE, "Only variables should be passed by reference"); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - ZEND_VM_RETURN(); +send_var: + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(Z_ISREF_P(varptr))) { + zend_refcounted *ref = Z_COUNTED_P(varptr); + + varptr = Z_REFVAL_P(varptr); + ZVAL_COPY_VALUE(arg, varptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(arg)) { + Z_ADDREF_P(arg); + } + } else { + ZVAL_COPY_VALUE(arg, varptr); + } + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *varptr, *arg; SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); + if (IS_UNUSED == IS_CONST) { + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + uint32_t arg_num; + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + } + + varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(varptr)) { + Z_ADDREF_P(varptr); + } else { + ZVAL_MAKE_REF_EX(varptr, 2); + } + ZVAL_REF(arg, Z_REF_P(varptr)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_STRICT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *varptr, *arg; + uint32_t arg_num; - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + if (IS_UNUSED == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + arg_num = opline->op2.num; + } - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} + if (EXPECTED(0)) { + if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_var_by_ref; + } + } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { +send_var_by_ref: + varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(varptr)) { + Z_ADDREF_P(varptr); + } else { + ZVAL_MAKE_REF_EX(varptr, 2); + } + ZVAL_REF(arg, Z_REF_P(varptr)); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *variable_ptr; + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE(); + } - SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(arg); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } - if (0 || UNEXPECTED(0)) { - zend_refcounted *garbage = NULL; + if (IS_VAR == IS_CV) { + ZVAL_COPY_DEREF(arg, varptr); + } else /* if (IS_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(varptr))) { + zend_refcounted *ref = Z_COUNTED_P(varptr); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(0)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); + varptr = Z_REFVAL_P(varptr); + ZVAL_COPY_VALUE(arg, varptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(arg)) { + Z_ADDREF_P(arg); + } + } else { + ZVAL_COPY_VALUE(arg, varptr); } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES()); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* zend_assign_to_variable() always takes care of op2, never free it! */ - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (0 || UNEXPECTED(1)) { - zend_refcounted *garbage = NULL; + zval *varptr, *arg; + uint32_t arg_num; - value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(1)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); + if (IS_UNUSED == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); } } else { - value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES()); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + arg_num = opline->op2.num; } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + if (EXPECTED(1)) { + if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_var_by_ref; + } + } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { +send_var_by_ref: + varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(varptr)) { + Z_ADDREF_P(varptr); + } else { + ZVAL_MAKE_REF_EX(varptr, 2); + } + ZVAL_REF(arg, Z_REF_P(varptr)); - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE(); + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_STRICT_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(arg); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} + if (IS_VAR == IS_CV) { + ZVAL_COPY_DEREF(arg, varptr); + } else /* if (IS_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(varptr))) { + zend_refcounted *ref = Z_COUNTED_P(varptr); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + varptr = Z_REFVAL_P(varptr); + ZVAL_COPY_VALUE(arg, varptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(arg)) { + Z_ADDREF_P(arg); + } + } else { + ZVAL_COPY_VALUE(arg, varptr); + } + } - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (0 || UNEXPECTED(0)) { - zend_refcounted *garbage = NULL; + zval *varptr, *arg; - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(0)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); + if (IS_UNUSED == IS_CONST) { + // TODO: Would it make sense to share the cache slot with CHECK_FUNC_ARG? + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + uint32_t arg_num; + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); } } else { - value = zend_assign_to_variable(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES()); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* zend_assign_to_variable() always takes care of op2, never free it! */ - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(varptr)) { + Z_ADDREF_P(varptr); + } else { + ZVAL_MAKE_REF_EX(varptr, 2); + } + ZVAL_REF(arg, Z_REF_P(varptr)); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *variable_ptr; + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE(); + } - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (0 || UNEXPECTED(1)) { - zend_refcounted *garbage = NULL; + if (UNEXPECTED(Z_ISREF_P(varptr))) { + zend_refcounted *ref = Z_COUNTED_P(varptr); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(1)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); + varptr = Z_REFVAL_P(varptr); + ZVAL_COPY_VALUE(arg, varptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(arg)) { + Z_ADDREF_P(arg); } } else { - value = zend_assign_to_variable(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES()); + ZVAL_COPY_VALUE(arg, varptr); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* zend_assign_to_variable() always takes care of op2, never free it! */ - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NEW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *variable_ptr; - zval *value_ptr; - zend_refcounted *garbage = NULL; + zval *result; + zend_function *constructor; + zend_class_entry *ce; + zend_execute_data *call; SAVE_OPLINE(); - value_ptr = _get_zval_ptr_ptr_var(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (IS_VAR == IS_VAR && - UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) { - - zend_throw_error(NULL, "Cannot assign by reference to an array dimension of an object"); - variable_ptr = &EG(uninitialized_zval); - } else if (IS_VAR == IS_VAR && - opline->extended_value == ZEND_RETURNS_FUNCTION && - UNEXPECTED(!Z_ISREF_P(value_ptr))) { - - variable_ptr = zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC); + if (IS_VAR == IS_CONST) { + ce = CACHED_PTR(opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + CACHE_PTR(opline->op2.num, ce); + } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } } else { - zend_assign_to_variable_reference(variable_ptr, value_ptr, &garbage); + ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr); + result = EX_VAR(opline->result.var); + if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { + ZVAL_UNDEF(result); + HANDLE_EXCEPTION(); } - if (garbage) { - GC_DTOR(garbage); + constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); + if (constructor == NULL) { + /* If there are no arguments, skip over the DO_FCALL opcode. We check if the next + * opcode is DO_FCALL in case EXT instructions are used. */ + if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) { + ZEND_VM_NEXT_OPCODE_EX(1, 2); + } + + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + + /* Perform a dummy function call */ + call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, + opline->extended_value, NULL); + } else { + if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { + init_func_run_time_cache(&constructor->op_array); + } + /* We are not handling overloaded classes right now */ + call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS, + constructor, + opline->extended_value, + Z_OBJ_P(result)); + Z_ADDREF_P(result); } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + call->prev_execute_data = EX(call); + EX(call) = call; + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; - zval *value, *container, *dim; - HashTable *ht; + zval *expr_ptr, new_expr; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -assign_dim_op_array: - SEPARATE_ARRAY(container); - ht = Z_ARRVAL_P(container); -assign_dim_op_new_array: - dim = NULL; - if (IS_UNUSED == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); - if (UNEXPECTED(!var_ptr)) { - zend_cannot_add_element(); - goto assign_dim_op_ret_null; - } + if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && + UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { + expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); } else { - if (IS_UNUSED == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); - } else { - var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(!var_ptr)) { - goto assign_dim_op_ret_null; - } + ZVAL_MAKE_REF_EX(expr_ptr, 2); } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } else { + expr_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_TMP_VAR) { + /* pass */ + } else if (IS_VAR == IS_CONST) { + Z_TRY_ADDREF_P(expr_ptr); + } else if (IS_VAR == IS_CV) { + ZVAL_DEREF(expr_ptr); + Z_TRY_ADDREF_P(expr_ptr); + } else /* if (IS_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(expr_ptr); - value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - - do { - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; + expr_ptr = Z_REFVAL_P(expr_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + ZVAL_COPY_VALUE(&new_expr, expr_ptr); + expr_ptr = &new_expr; + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); } } - zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); - } while (0); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - } - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - } else { - if (EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto assign_dim_op_array; - } } + } - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(container); + if (IS_UNUSED != IS_UNUSED) { + zval *offset = NULL; + zend_string *str; + zend_ulong hval; - dim = NULL; - if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; +add_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_UNUSED != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index; + } } - zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); - } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - uint8_t old_type; - - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); +str_index: + zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index: + zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); + } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto add_again; + } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { + zval tmp; + if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { + ZVAL_COPY(&tmp, expr_ptr); } - ht = zend_new_array(8); - old_type = Z_TYPE_P(container); - ZVAL_ARR(container, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_op_ret_null; - } + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { + /* A userland error handler can do funky things to the expression, so reset it */ + zval_ptr_dtor(expr_ptr); + ZVAL_COPY_VALUE(expr_ptr, &tmp); } - goto assign_dim_op_new_array; - } else { - dim = NULL; - zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); -assign_dim_op_ret_null: - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); + if (UNEXPECTED(EG(exception))) { + zval_ptr_dtor_nogc(expr_ptr); + HANDLE_EXCEPTION(); } + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + goto num_index; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); + hval = Z_RES_HANDLE_P(offset); + goto num_index; + } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else { + zend_illegal_array_offset_access(offset); + zval_ptr_dtor_nogc(expr_ptr); } - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_EX(1, 2); + } else { + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(expr_ptr); + } + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zval *array; + uint32_t size; USE_OPLINE - zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_W(container, NULL, IS_UNUSED OPLINE_CC EXECUTE_DATA_CC); + array = EX_VAR(opline->result.var); + if (IS_VAR != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_ARR(array, zend_new_array(0)); + ZEND_VM_NEXT_OPCODE(); + } +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + var_ptr = EX_VAR(opline->op1.var); + if (UNEXPECTED(Z_ISREF_P(var_ptr))) { + if (UNEXPECTED(Z_REFCOUNT_P(var_ptr) == 1)) { + ZVAL_UNREF(var_ptr); + } } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; + + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_RW(container, NULL, IS_UNUSED OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ -#if 0 - USE_OPLINE -#endif + /* Set the new yielded value */ + if (IS_VAR != IS_UNUSED) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_VAR & (IS_CONST|IS_TMP_VAR)) { + zval *value; - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + + value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } + } else { + zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + do { + if (IS_VAR == IS_VAR) { + ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION + && !Z_ISREF_P(value_ptr)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + ZVAL_COPY(&generator->value, value_ptr); + break; + } + } + if (Z_ISREF_P(value_ptr)) { + Z_ADDREF_P(value_ptr); + } else { + ZVAL_MAKE_REF_EX(value_ptr, 2); + } + ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); + } while (0); + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } + } else { + zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + /* Consts, temporary variables and references need copying */ + if (IS_VAR == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } else if (IS_VAR == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } else { + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } + } } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - if (IS_UNUSED == IS_UNUSED) { - ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); + } + + /* Set the new yielded key */ + if (IS_UNUSED != IS_UNUSED) { + zval *key = NULL; + if ((IS_UNUSED & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + key = Z_REFVAL_P(key); } - ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZVAL_COPY(&generator->key, key); + + + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); + } + } else { + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); + } + + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; } + + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); + + ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MAKE_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zval *op1 = EX_VAR(opline->op1.var); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_UNUSED == IS_UNUSED) { - value = RT_CONSTANT((opline+1), (opline+1)->op1); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_CONST == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_CONST == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } + if (IS_VAR == IS_CV) { + if (UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_NEW_EMPTY_REF(op1); + Z_SET_REFCOUNT_P(op1, 2); + ZVAL_NULL(Z_REFVAL_P(op1)); + ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); } else { - dim = NULL; - if (IS_UNUSED == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + if (Z_ISREF_P(op1)) { + Z_ADDREF_P(op1); } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; + ZVAL_MAKE_REF_EX(op1, 2); } - value = RT_CONSTANT((opline+1), (opline+1)->op1); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); } - if (garbage) { - GC_DTOR_NO_REF(garbage); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_INDIRECT)) { + op1 = Z_INDIRECT_P(op1); + if (EXPECTED(!Z_ISREF_P(op1))) { + ZVAL_MAKE_REF_EX(op1, 2); + } else { + GC_ADDREF(Z_REF_P(op1)); } + ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), op1); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DEREF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + if (Z_TYPE_P(value) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(value); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(EX_VAR(opline->result.var)); } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); + } else { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + } - GC_ADDREF(obj); - dim = NULL; - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } + ZEND_VM_NEXT_OPCODE(); +} - value = RT_CONSTANT((opline+1), (opline+1)->op1); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_CONST & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varptr, *arg; + uint32_t arg_num = opline->op2.num; - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_UNUSED == IS_UNUSED) { - zend_use_new_element_for_string(); + if (IS_VAR == IS_CV) { + ZVAL_COPY(arg, varptr); + } else /* if (IS_VAR == IS_VAR) */ { + ZVAL_COPY_VALUE(arg, varptr); + } + ZEND_VM_NEXT_OPCODE(); +} - UNDEF_RESULT(); - } else { - dim = NULL; - value = RT_CONSTANT((opline+1), (opline+1)->op1); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *object; + zval *property; + zval *value; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + do { + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_op_object; } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = NULL; - + if (IS_VAR == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } +assign_op_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { UNDEF_RESULT(); + break; + } + } + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); + zend_reference *ref; - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + zptr = Z_REFVAL_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; + } } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = NULL; -assign_dim_error: + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + if (prop_info) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_binary_op(zptr, zptr, value OPLINE_CC); + } + } while (0); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), zptr); + } } + } else { + zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); } - } - if (IS_UNUSED != IS_UNUSED) { + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); + + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ + /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; + zval *var_ptr; + zval *value, *container, *dim; + HashTable *ht; SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_UNUSED == IS_UNUSED) { - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +assign_dim_op_array: + SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); +assign_dim_op_new_array: + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_UNUSED) { + var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); + if (UNEXPECTED(!var_ptr)) { zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_TMP_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_TMP_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } + goto assign_dim_op_ret_null; } } else { - dim = NULL; - if (IS_UNUSED == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + if (IS_CV == IS_CONST) { + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; + if (UNEXPECTED(!var_ptr)) { + goto assign_dim_op_ret_null; } - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); } + + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); + + do { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; + } + } + zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); + } while (0); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; + if (EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto assign_dim_op_array; } } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); - dim = NULL; - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; } + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + uint8_t old_type; - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_UNUSED == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = NULL; - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = NULL; - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } + ht = zend_new_array(8); + old_type = Z_TYPE_P(container); + ZVAL_ARR(container, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_op_ret_null; } - goto try_assign_dim_array; } + goto assign_dim_op_new_array; } else { - zend_use_scalar_as_array(); - dim = NULL; -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); +assign_dim_op_ret_null: + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } } - if (IS_UNUSED != IS_UNUSED) { - } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; + zval *var_ptr; zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_UNUSED == IS_UNUSED) { - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = NULL; - if (IS_UNUSED == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; } } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); + zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); + } while (0); - GC_ADDREF(obj); - dim = NULL; - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; + + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + + do { + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto pre_incdec_object; } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_UNUSED == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = NULL; - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (IS_VAR == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = NULL; - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } +pre_incdec_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + UNDEF_RESULT(); + break; + } + } + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); } - goto try_assign_dim_array; + } else { + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); + zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { - zend_use_scalar_as_array(); - dim = NULL; -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } + zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); } - } - if (IS_UNUSED != IS_UNUSED) { + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); - } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_UNUSED == IS_UNUSED) { - value = EX_VAR((opline+1)->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_DEREF(value); + do { + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto post_incdec_object; } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_CV == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_CV == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } + if (IS_VAR == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } + +post_incdec_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + name = Z_STR_P(property); } else { - dim = NULL; - if (IS_UNUSED == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; } - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } + } else { + zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); - GC_ADDREF(obj); - dim = NULL; - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - value = EX_VAR((opline+1)->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_CV & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zend_fetch_dimension_address_W(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_UNUSED == IS_UNUSED) { - zend_use_new_element_for_string(); + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - UNDEF_RESULT(); - } else { - dim = NULL; - value = EX_VAR((opline+1)->op1.var); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zend_fetch_dimension_address_RW(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = NULL; + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ +#if 0 + USE_OPLINE +#endif - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if (IS_CV == IS_UNUSED) { + ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + if (IS_VAR & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = NULL; -assign_dim_error: - - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); } } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - if (IS_UNUSED != IS_UNUSED) { +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zend_fetch_dimension_address_UNSET(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zend_class_entry *ce; - uint32_t call_info; - zend_function *fbc; - zend_execute_data *call; + zval *property, *container, *result; SAVE_OPLINE(); - if (IS_VAR == IS_CONST) { - /* no function found. try a static method in class */ - ce = CACHED_PTR(opline->result.num); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - - - HANDLE_EXCEPTION(); - } - if (IS_UNUSED != IS_CONST) { - CACHE_PTR(opline->result.num, ce); - } - } - } else if (IS_VAR == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + zend_fetch_property_address( + result, container, IS_VAR, property, IS_CV, + ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - if (IS_VAR == IS_CONST && - IS_UNUSED == IS_CONST && - EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { - /* nothing to do */ - } else if (IS_VAR != IS_CONST && - IS_UNUSED == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else if (IS_UNUSED != IS_UNUSED) { - function_name = NULL; - if (IS_UNUSED != IS_CONST) { - if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if (IS_UNUSED & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Method name must be a string"); - - - HANDLE_EXCEPTION(); - } while (0); - } - } - - if (ce->get_static_method) { - fbc = ce->get_static_method(ce, Z_STR_P(function_name)); - } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - } - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(ce, Z_STR_P(function_name)); - } - - - HANDLE_EXCEPTION(); - } - if (IS_UNUSED == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { - CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - if (IS_UNUSED != IS_CONST) { +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *property, *container, *result; + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - } - } else { - if (UNEXPECTED(ce->constructor == NULL)) { - zend_throw_error(NULL, "Cannot call constructor"); - HANDLE_EXCEPTION(); - } - if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { - zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); - HANDLE_EXCEPTION(); - } - fbc = ce->constructor; - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - } - if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { - if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - ce = (zend_class_entry*)Z_OBJ(EX(This)); - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - } else { - zend_non_static_method_call(fbc); - HANDLE_EXCEPTION(); - } - } else { - /* previous opcode is ZEND_FETCH_CLASS */ - if (IS_VAR == IS_UNUSED - && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { - if (Z_TYPE(EX(This)) == IS_OBJECT) { - ce = Z_OBJCE(EX(This)); - } else { - ce = Z_CE(EX(This)); - } - } - call_info = ZEND_CALL_NESTED_FUNCTION; + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } - - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, ce); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - if (IS_VAR == IS_UNUSED) { - SAVE_OPLINE(); - zend_verify_missing_return_type(EX(func)); - HANDLE_EXCEPTION(); - } else { -/* prevents "undefined variable opline" errors */ -#if 0 || (IS_VAR != IS_UNUSED) - USE_OPLINE - zval *retval_ref, *retval_ptr; - zend_arg_info *ret_info = EX(func)->common.arg_info - 1; - retval_ref = retval_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (IS_VAR == IS_CONST) { - ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr); - retval_ref = retval_ptr = EX_VAR(opline->result.var); - } else if (IS_VAR == IS_VAR) { - if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) { - retval_ref = retval_ptr = Z_INDIRECT_P(retval_ptr); - } - ZVAL_DEREF(retval_ptr); - } else if (IS_VAR == IS_CV) { - ZVAL_DEREF(retval_ptr); - } - - if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { - ZEND_VM_NEXT_OPCODE(); - } +#if 0 + USE_OPLINE +#endif - if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { - SAVE_OPLINE(); - retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { - ZEND_VM_NEXT_OPCODE(); - } + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + /* Behave like FETCH_OBJ_W */ + if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - - zend_reference *ref = NULL; - if (UNEXPECTED(retval_ref != retval_ptr)) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - ref = Z_REF_P(retval_ref); - } else { - /* A cast might happen - unwrap the reference if this is a by-value return */ - if (Z_REFCOUNT_P(retval_ref) == 1) { - ZVAL_UNREF(retval_ref); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if (IS_VAR == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); } else { - Z_DELREF_P(retval_ref); - ZVAL_COPY(retval_ref, retval_ptr); + Z_TRY_ADDREF_P(op1); } - retval_ptr = retval_ref; } } - - SAVE_OPLINE(); - if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, 1, 0))) { - zend_verify_return_error(EX(func), retval_ptr); - HANDLE_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); -#endif + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *varptr, *arg; - - if (IS_UNUSED == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - uint32_t arg_num; - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - } + zval *container, *property, *result; - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(arg); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - if (IS_VAR == IS_CV) { - ZVAL_COPY_DEREF(arg, varptr); - } else /* if (IS_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(varptr))) { - zend_refcounted *ref = Z_COUNTED_P(varptr); - varptr = Z_REFVAL_P(varptr); - ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); - } - } else { - ZVAL_COPY_VALUE(arg, varptr); - } + if (IS_VAR == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } - - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *varptr, *arg; + zval *container, *dim; - if (IS_UNUSED == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - uint32_t arg_num; - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } + SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + dim = EX_VAR(opline->op2.var); + + if (IS_VAR == IS_VAR + && Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT + && UNEXPECTED(!Z_ISREF_P(container)) + ) { + zend_error(E_NOTICE, "Attempting to set reference to non referenceable value"); + zend_fetch_dimension_address_LIST_r(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC); } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); + zend_fetch_dimension_address_W(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC); } - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(arg, varptr); - - if (EXPECTED(Z_ISREF_P(varptr))) { - ZEND_VM_NEXT_OPCODE(); - } - SAVE_OPLINE(); - ZVAL_NEW_REF(arg, arg); - zend_error(E_NOTICE, "Only variables should be passed by reference"); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *varptr, *arg; - uint32_t arg_num; + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; - if (IS_UNUSED == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + value = RT_CONSTANT((opline+1), (opline+1)->op1); + + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - arg_num = opline->op2.num; + zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; } - if (EXPECTED(0)) { - if (!QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - goto send_var; - } +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(arg, varptr); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (EXPECTED(Z_ISREF_P(varptr) || - QUICK_ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) { - ZEND_VM_NEXT_OPCODE(); +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CONST != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CONST == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CONST == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ + } } + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); } else { - if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - goto send_var; - } + name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(arg, varptr); - if (EXPECTED(Z_ISREF_P(varptr) || - ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) { - ZEND_VM_NEXT_OPCODE(); + UNDEF_RESULT(); + goto exit_assign_obj; } } - SAVE_OPLINE(); - ZVAL_NEW_REF(arg, arg); - zend_error(E_NOTICE, "Only variables should be passed by reference"); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_DEREF(value); + } -send_var: - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(Z_ISREF_P(varptr))) { - zend_refcounted *ref = Z_COUNTED_P(varptr); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - varptr = Z_REFVAL_P(varptr); - ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); - } - } else { - ZVAL_COPY_VALUE(arg, varptr); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr, *arg; - uint32_t arg_num; - if (IS_UNUSED == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - arg_num = opline->op2.num; +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); } - if (EXPECTED(1)) { - if (!QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - goto send_var; - } - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(arg, varptr); +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); + } - if (EXPECTED(Z_ISREF_P(varptr) || - QUICK_ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) { - ZEND_VM_NEXT_OPCODE(); - } - } else { - if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - goto send_var; - } - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(arg, varptr); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} - if (EXPECTED(Z_ISREF_P(varptr) || - ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num))) { - ZEND_VM_NEXT_OPCODE(); - } - } +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - ZVAL_NEW_REF(arg, arg); - zend_error(E_NOTICE, "Only variables should be passed by reference"); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - -send_var: - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(Z_ISREF_P(varptr))) { - zend_refcounted *ref = Z_COUNTED_P(varptr); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - varptr = Z_REFVAL_P(varptr); - ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; } - } else { - ZVAL_COPY_VALUE(arg, varptr); + zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; } - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr, *arg; +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - SAVE_OPLINE(); - if (IS_UNUSED == IS_CONST) { - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - uint32_t arg_num; - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_TMP_VAR == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_TMP_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ + } } + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); + name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + goto exit_assign_obj; + } } - varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(varptr)) { - Z_ADDREF_P(varptr); - } else { - ZVAL_MAKE_REF_EX(varptr, 2); + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_DEREF(value); } - ZVAL_REF(arg, Z_REF_P(varptr)); - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr, *arg; - uint32_t arg_num; + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if (IS_UNUSED == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - arg_num = opline->op2.num; + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } - if (EXPECTED(0)) { - if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - goto send_var_by_ref; - } - } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { -send_var_by_ref: - varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(varptr)) { - Z_ADDREF_P(varptr); - } else { - ZVAL_MAKE_REF_EX(varptr, 2); - } - ZVAL_REF(arg, Z_REF_P(varptr)); - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); } - - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(arg); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); } - if (IS_VAR == IS_CV) { - ZVAL_COPY_DEREF(arg, varptr); - } else /* if (IS_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(varptr))) { - zend_refcounted *ref = Z_COUNTED_P(varptr); - - varptr = Z_REFVAL_P(varptr); - ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); - } - } else { - ZVAL_COPY_VALUE(arg, varptr); - } - } - ZEND_VM_NEXT_OPCODE(); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_VAR_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *varptr, *arg; - uint32_t arg_num; + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; - if (IS_UNUSED == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - arg_num = opline->op2.num; - } + SAVE_OPLINE(); + object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - if (EXPECTED(1)) { - if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - goto send_var_by_ref; - } - } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { -send_var_by_ref: - varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(varptr)) { - Z_ADDREF_P(varptr); - } else { - ZVAL_MAKE_REF_EX(varptr, 2); + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; } - ZVAL_REF(arg, Z_REF_P(varptr)); - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); - } - - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(arg); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; } - if (IS_VAR == IS_CV) { - ZVAL_COPY_DEREF(arg, varptr); - } else /* if (IS_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(varptr))) { - zend_refcounted *ref = Z_COUNTED_P(varptr); - - varptr = Z_REFVAL_P(varptr); - ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); - } - } else { - ZVAL_COPY_VALUE(arg, varptr); - } - } +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - ZEND_VM_NEXT_OPCODE(); -} + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr, *arg; +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } - if (IS_UNUSED == IS_CONST) { - // TODO: Would it make sense to share the cache slot with CHECK_FUNC_ARG? - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - uint32_t arg_num; - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CV != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CV == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CV == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ + } } + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - } - - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - varptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(varptr)) { - Z_ADDREF_P(varptr); - } else { - ZVAL_MAKE_REF_EX(varptr, 2); - } - ZVAL_REF(arg, Z_REF_P(varptr)); - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); - } - - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { - if (UNEXPECTED(Z_ISREF_P(varptr))) { - zend_refcounted *ref = Z_COUNTED_P(varptr); - varptr = Z_REFVAL_P(varptr); - ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); + UNDEF_RESULT(); + goto exit_assign_obj; } - } else { - ZVAL_COPY_VALUE(arg, varptr); } - ZEND_VM_NEXT_OPCODE(); -} + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_DEREF(value); + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NEW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *result; - zend_function *constructor; - zend_class_entry *ce; - zend_execute_data *call; + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - SAVE_OPLINE(); - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - CACHE_PTR(opline->op2.num, ce); - } - } else if (IS_VAR == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } - result = EX_VAR(opline->result.var); - if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { - ZVAL_UNDEF(result); - HANDLE_EXCEPTION(); +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); } - constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); - if (constructor == NULL) { - /* If there are no arguments, skip over the DO_FCALL opcode. We check if the next - * opcode is DO_FCALL in case EXT instructions are used. */ - if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) { - ZEND_VM_NEXT_OPCODE_EX(1, 2); - } - - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - /* Perform a dummy function call */ - call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, - opline->extended_value, NULL); - } else { - if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { - init_func_run_time_cache(&constructor->op_array); - } - /* We are not handling overloaded classes right now */ - call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS, - constructor, - opline->extended_value, - Z_OBJ_P(result)); - Z_ADDREF_P(result); +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); } - call->prev_execute_data = EX(call); - EX(call) = call; - ZEND_VM_NEXT_OPCODE(); + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *expr_ptr, new_expr; - + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; + SAVE_OPLINE(); - if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && - UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } else { - ZVAL_MAKE_REF_EX(expr_ptr, 2); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } else { - expr_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_TMP_VAR) { - /* pass */ - } else if (IS_VAR == IS_CONST) { - Z_TRY_ADDREF_P(expr_ptr); - } else if (IS_VAR == IS_CV) { - ZVAL_DEREF(expr_ptr); - Z_TRY_ADDREF_P(expr_ptr); - } else /* if (IS_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(expr_ptr); + orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - ZVAL_COPY_VALUE(&new_expr, expr_ptr); - expr_ptr = &new_expr; - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_CV == IS_UNUSED) { + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); } - } - } - } - - if (IS_UNUSED != IS_UNUSED) { - zval *offset = NULL; - zend_string *str; - zend_ulong hval; - -add_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_UNUSED != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index; + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; } } -str_index: - zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index: - zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto add_again; - } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { - zval tmp; - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_COPY(&tmp, expr_ptr); - } - zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - /* A userland error handler can do funky things to the expression, so reset it */ - zval_ptr_dtor(expr_ptr); - ZVAL_COPY_VALUE(expr_ptr, &tmp); + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_DEREF(value); } - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(expr_ptr); - HANDLE_EXCEPTION(); + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_CONST == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } else if (IS_CONST == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } } - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); - goto num_index; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - zend_use_resource_as_offset(offset); - hval = Z_RES_HANDLE_P(offset); - goto num_index; - } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - str = ZSTR_EMPTY_ALLOC(); - goto str_index; } else { - zend_illegal_array_offset_access(offset); - zval_ptr_dtor_nogc(expr_ptr); + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + value = RT_CONSTANT((opline+1), (opline+1)->op1); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); } - - - } else { - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { - zend_cannot_add_element(); - zval_ptr_dtor_nogc(expr_ptr); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); } - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zval *array; - uint32_t size; - USE_OPLINE - - SAVE_OPLINE(); - array = EX_VAR(opline->result.var); - if (IS_VAR != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + if (garbage) { + GC_DTOR_NO_REF(garbage); } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZVAL_ARR(array, zend_new_array(0)); - ZEND_VM_NEXT_OPCODE(); - } -} + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; + GC_ADDREF(obj); + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } - var_ptr = EX_VAR(opline->op1.var); - if (UNEXPECTED(Z_ISREF_P(var_ptr))) { - if (UNEXPECTED(Z_REFCOUNT_P(var_ptr) == 1)) { - ZVAL_UNREF(var_ptr); - } - } + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_CONST & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } - ZEND_VM_NEXT_OPCODE(); -} + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_CV == IS_UNUSED) { + zend_use_new_element_for_string(); - SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); + UNDEF_RESULT(); + } else { + dim = EX_VAR(opline->op2.var); + value = RT_CONSTANT((opline+1), (opline+1)->op1); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); - /* Set the new yielded value */ - if (IS_VAR != IS_UNUSED) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_VAR & (IS_CONST|IS_TMP_VAR)) { - zval *value; + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } + UNDEF_RESULT(); } else { - zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - do { - if (IS_VAR == IS_VAR) { - ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION - && !Z_ISREF_P(value_ptr)) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - ZVAL_COPY(&generator->value, value_ptr); - break; - } - } - if (Z_ISREF_P(value_ptr)) { - Z_ADDREF_P(value_ptr); - } else { - ZVAL_MAKE_REF_EX(value_ptr, 2); + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; } - ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); - } while (0); - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } + goto try_assign_dim_array; } } else { - zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zend_use_scalar_as_array(); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); +assign_dim_error: - /* Consts, temporary variables and references need copying */ - if (IS_VAR == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } else if (IS_VAR == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); } } - } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); } + if (IS_CV != IS_UNUSED) { - /* Set the new yielded key */ - if (IS_UNUSED != IS_UNUSED) { - zval *key = NULL; - if ((IS_UNUSED & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { - key = Z_REFVAL_P(key); - } - ZVAL_COPY(&generator->key, key); - - - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); - } - } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); - } - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); - } else { - generator->send_target = NULL; } - - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); - - ZEND_VM_RETURN(); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MAKE_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1 = EX_VAR(opline->op1.var); + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; - if (IS_VAR == IS_CV) { - if (UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_NEW_EMPTY_REF(op1); - Z_SET_REFCOUNT_P(op1, 2); - ZVAL_NULL(Z_REFVAL_P(op1)); - ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); + SAVE_OPLINE(); + orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_CV == IS_UNUSED) { + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_DEREF(value); + } + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_TMP_VAR == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } else if (IS_TMP_VAR == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } } else { - if (Z_ISREF_P(op1)) { - Z_ADDREF_P(op1); + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { - ZVAL_MAKE_REF_EX(op1, 2); + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } - ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_INDIRECT)) { - op1 = Z_INDIRECT_P(op1); - if (EXPECTED(!Z_ISREF_P(op1))) { - ZVAL_MAKE_REF_EX(op1, 2); - } else { - GC_ADDREF(Z_REF_P(op1)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); } - ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); - } else { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), op1); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_TYPE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1; - zend_string *type; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - type = zend_zval_get_legacy_type(op1); - if (EXPECTED(type)) { - ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type); } else { - ZVAL_STRING(EX_VAR(opline->result.var), "unknown type"); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr, *arg; - uint32_t arg_num = opline->op2.num; + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); - if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } + GC_ADDREF(obj); + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } - varptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - arg = ZEND_CALL_VAR(EX(call), opline->result.var); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } - if (IS_VAR == IS_CV) { - ZVAL_COPY(arg, varptr); - } else /* if (IS_VAR == IS_VAR) */ { - ZVAL_COPY_VALUE(arg, varptr); - } + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - ZEND_VM_NEXT_OPCODE(); -} + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_CV == IS_UNUSED) { + zend_use_new_element_for_string(); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + } else { + dim = EX_VAR(opline->op2.var); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + } else { + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CASE_STRICT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - - - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object; - zval *property; - zval *value; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; - - SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - - do { - value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_op_object; - } - if (IS_VAR == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; - } - -assign_op_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - UNDEF_RESULT(); - break; - } - } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - zend_reference *ref; - - do { - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - zptr = Z_REFVAL_P(zptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - if (prop_info) { - /* special case for typed properties */ - zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_binary_op(zptr, zptr, value OPLINE_CC); + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; } - } while (0); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), zptr); } + goto try_assign_dim_array; } } else { - zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); - } - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + zend_use_scalar_as_array(); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); +assign_dim_error: + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } - } while (0); - - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + } + if (IS_CV != IS_UNUSED) { + } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_obj has two opcodes! */ + /* assign_dim has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; - zval *value, *container, *dim; - HashTable *ht; + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -assign_dim_op_array: - SEPARATE_ARRAY(container); - ht = Z_ARRVAL_P(container); -assign_dim_op_new_array: - dim = EX_VAR(opline->op2.var); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); if (IS_CV == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); - if (UNEXPECTED(!var_ptr)) { + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_DEREF(value); + } + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { zend_cannot_add_element(); - goto assign_dim_op_ret_null; + goto assign_dim_error; + } else if (IS_CV == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } else if (IS_CV == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } } } else { + dim = EX_VAR(opline->op2.var); if (IS_CV == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { - var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } - if (UNEXPECTED(!var_ptr)) { - goto assign_dim_op_ret_null; + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; } + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); } - - value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - - do { - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); - } while (0); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); } - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); } else { - if (EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto assign_dim_op_array; + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; } } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(container); - + GC_ADDREF(obj); dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); - } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - uint8_t old_type; - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_CV & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); } - ht = zend_new_array(8); - old_type = Z_TYPE_P(container); - ZVAL_ARR(container, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_op_ret_null; + + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + + + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_CV == IS_UNUSED) { + zend_use_new_element_for_string(); + + + UNDEF_RESULT(); + } else { + dim = EX_VAR(opline->op2.var); + value = EX_VAR((opline+1)->op1.var); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + + + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + + + UNDEF_RESULT(); + } else { + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } } + goto try_assign_dim_array; } - goto assign_dim_op_new_array; } else { + zend_use_scalar_as_array(); dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); -assign_dim_op_ret_null: - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); +assign_dim_error: + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } } + if (IS_CV != IS_UNUSED) { + } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* assign_dim has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; zval *value; + zval *variable_ptr; SAVE_OPLINE(); value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - do { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); - } while (0); + if (0 || UNEXPECTED(0)) { + zend_refcounted *garbage = NULL; - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); } - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* zend_assign_to_variable() always takes care of op2, never free it! */ + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; + zval *value; + zval *variable_ptr; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - do { - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto pre_incdec_object; - } - if (IS_VAR == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; - } + if (0 || UNEXPECTED(1)) { + zend_refcounted *garbage = NULL; -pre_incdec_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - UNDEF_RESULT(); - break; - } - } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); - } - } else { - zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(1)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); } - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + if (garbage) { + GC_DTOR_NO_REF(garbage); } - } while (0); - - + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); + } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* zend_assign_to_variable() always takes care of op2, never free it! */ + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; + zval *variable_ptr; + zval *value_ptr; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - do { - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto post_incdec_object; - } - if (IS_VAR == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; - } + if (IS_VAR == IS_VAR && + UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) { -post_incdec_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; - } - } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); - } - } else { - zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); - } - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - } while (0); + zend_throw_error(NULL, "Cannot assign by reference to an array dimension of an object"); + variable_ptr = &EG(uninitialized_zval); + } else if (IS_CV == IS_VAR && + opline->extended_value == ZEND_RETURNS_FUNCTION && + UNEXPECTED(!Z_ISREF_P(value_ptr))) { + + variable_ptr = zend_wrong_assign_to_variable_reference( + variable_ptr, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_variable_reference(variable_ptr, value_ptr, &garbage); + } + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr); + } + + if (garbage) { + GC_DTOR(garbage); + } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; + zval *property, *container, *value_ptr; SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_W(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + if (1) { + if (IS_VAR == IS_UNUSED) { + if (IS_CV == IS_CONST) { + zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } + } else { + if (IS_CV == IS_CONST) { + zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } + } + } else { + zend_assign_to_property_reference(container, IS_VAR, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; + zval *property, *container, *value_ptr; SAVE_OPLINE(); + container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_RW(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + if (1) { + if (IS_VAR == IS_UNUSED) { + if (IS_CV == IS_CONST) { + zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } + } else { + if (IS_CV == IS_CONST) { + zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } + } + } else { + zend_assign_to_property_reference(container, IS_VAR, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + + + + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if 0 USE_OPLINE -#endif + zval *function_name; + zend_class_entry *ce; + uint32_t call_info; + zend_function *fbc; + zend_execute_data *call; - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + SAVE_OPLINE(); + + if (IS_VAR == IS_CONST) { + /* no function found. try a static method in class */ + ce = CACHED_PTR(opline->result.num); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + + + HANDLE_EXCEPTION(); + } + if (IS_CV != IS_CONST) { + CACHE_PTR(opline->result.num, ce); + } } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - if (IS_CV == IS_UNUSED) { - ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + + + HANDLE_EXCEPTION(); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); } -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; + if (IS_VAR == IS_CONST && + IS_CV == IS_CONST && + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { + /* nothing to do */ + } else if (IS_VAR != IS_CONST && + IS_CV == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else if (IS_CV != IS_UNUSED) { + function_name = EX_VAR(opline->op2.var); + if (IS_CV != IS_CONST) { + if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if (IS_CV & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Method name must be a string"); - SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_UNSET(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); + HANDLE_EXCEPTION(); + } while (0); + } + } - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + if (ce->get_static_method) { + fbc = ce->get_static_method(ce, Z_STR_P(function_name)); + } else { + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + } + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(ce, Z_STR_P(function_name)); + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *property, *container, *result; - SAVE_OPLINE(); + HANDLE_EXCEPTION(); + } + if (IS_CV == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + if (IS_CV != IS_CONST) { - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address( - result, container, IS_VAR, property, IS_CV, - ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); + } + } else { + if (UNEXPECTED(ce->constructor == NULL)) { + zend_throw_error(NULL, "Cannot call constructor"); + HANDLE_EXCEPTION(); + } + if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { + zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); + HANDLE_EXCEPTION(); + } + fbc = ce->constructor; + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + } - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + } else { + zend_non_static_method_call(fbc); + HANDLE_EXCEPTION(); + } + } else { + /* previous opcode is ZEND_FETCH_CLASS */ + if (IS_VAR == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { + if (Z_TYPE(EX(This)) == IS_OBJECT) { + ce = Z_OBJCE(EX(This)); + } else { + ce = Z_CE(EX(This)); + } + } + call_info = ZEND_CALL_NESTED_FUNCTION; } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *property, *container, *result; + zval *expr_ptr, new_expr; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && + UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { + expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } else { + ZVAL_MAKE_REF_EX(expr_ptr, 2); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } else { + expr_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if (IS_VAR == IS_TMP_VAR) { + /* pass */ + } else if (IS_VAR == IS_CONST) { + Z_TRY_ADDREF_P(expr_ptr); + } else if (IS_VAR == IS_CV) { + ZVAL_DEREF(expr_ptr); + Z_TRY_ADDREF_P(expr_ptr); + } else /* if (IS_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(expr_ptr); + + expr_ptr = Z_REFVAL_P(expr_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + ZVAL_COPY_VALUE(&new_expr, expr_ptr); + expr_ptr = &new_expr; + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } + } + } + } + if (IS_CV != IS_UNUSED) { + zval *offset = EX_VAR(opline->op2.var); + zend_string *str; + zend_ulong hval; - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); +add_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_CV != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index; + } + } +str_index: + zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index: + zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto add_again; + } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { + zval tmp; + if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { + ZVAL_COPY(&tmp, expr_ptr); + } + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { + /* A userland error handler can do funky things to the expression, so reset it */ + zval_ptr_dtor(expr_ptr); + ZVAL_COPY_VALUE(expr_ptr, &tmp); + } + if (UNEXPECTED(EG(exception))) { + zval_ptr_dtor_nogc(expr_ptr); + HANDLE_EXCEPTION(); + } + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + goto num_index; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); + hval = Z_RES_HANDLE_P(offset); + goto num_index; + } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else { + zend_illegal_array_offset_access(offset); + zval_ptr_dtor_nogc(expr_ptr); + } + + + } else { + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(expr_ptr); + } } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if 0 + zval *array; + uint32_t size; USE_OPLINE -#endif - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - /* Behave like FETCH_OBJ_W */ - if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + SAVE_OPLINE(); + array = EX_VAR(opline->result.var); + if (IS_VAR != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZVAL_ARR(array, zend_new_array(0)); + ZEND_VM_NEXT_OPCODE(); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container, *property, *result; + zval *container; + zval *offset; + zend_ulong hval; + zend_string *key; SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + offset = EX_VAR(opline->op2.var); + do { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; - if (IS_VAR == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } +unset_dim_array: + SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); +offset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + key = Z_STR_P(offset); + if (IS_CV != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(key, hval)) { + goto num_index_dim; + } + } +str_index_dim: + ZEND_ASSERT(ht != &EG(symbol_table)); + zend_hash_del(ht, key); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_dim: + zend_hash_index_del(ht, hval); + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto offset_again; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + /* The array may be destroyed while throwing a warning in case the float is not representable as an int. + * Temporarily increase the refcount to detect this situation. */ + GC_TRY_ADDREF(ht); + hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + break; + } + if (EG(exception)) { + break; + } + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_NULL) { + key = ZSTR_EMPTY_ALLOC(); + goto str_index_dim; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + key = ZSTR_EMPTY_ALLOC(); + goto str_index_dim; + } else { + zend_illegal_array_offset_unset(offset); + } + break; + } else if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto unset_dim_array; + } + } + if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + container = ZVAL_UNDEFINED_OP1(); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + offset = ZVAL_UNDEFINED_OP2(); + } + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; + } + Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset); + } else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { + zend_throw_error(NULL, "Cannot unset string offsets"); + } else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) { + zend_throw_error(NULL, "Cannot unset offset in a non-array variable"); + } else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) { + zend_false_to_array_deprecated(); + } + } while (0); + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_LIST_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container, *dim; + zval *container; + zval *offset; + zend_string *name, *tmp_name; SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - dim = EX_VAR(opline->op2.var); + offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if (IS_VAR == IS_VAR - && Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT - && UNEXPECTED(!Z_ISREF_P(container)) - ) { - zend_error(E_NOTICE, "Attempting to set reference to non referenceable value"); - zend_fetch_dimension_address_LIST_r(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_fetch_dimension_address_W(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC); - } + do { + if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + if (IS_VAR == IS_CV + && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + break; + } + } else { + break; + } + } + if (IS_CV == IS_CONST) { + name = Z_STR_P(offset); + } else { + name = zval_try_get_tmp_string(offset, &tmp_name); + if (UNEXPECTED(!name)) { + break; + } + } + Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - value = RT_CONSTANT((opline+1), (opline+1)->op1); + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; + SAVE_OPLINE(); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; + /* Set the new yielded value */ + if (IS_VAR != IS_UNUSED) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_VAR & (IS_CONST|IS_TMP_VAR)) { + zval *value; + + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + + value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); } } + } else { + zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CONST != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CONST == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_CONST == IS_CV) { - Z_TRY_ADDREF_P(value); + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + do { + if (IS_VAR == IS_VAR) { + ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION + && !Z_ISREF_P(value_ptr)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + ZVAL_COPY(&generator->value, value_ptr); + break; } } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + if (Z_ISREF_P(value_ptr)) { + Z_ADDREF_P(value_ptr); + } else { + ZVAL_MAKE_REF_EX(value_ptr, 2); } - goto exit_assign_obj; + ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); + } while (0); + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } + } else { + zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + /* Consts, temporary variables and references need copying */ + if (IS_VAR == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); } + } else if (IS_VAR == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - /* Fall through to write_property for hooks. */ } } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); + } + + /* Set the new yielded key */ + if (IS_CV != IS_UNUSED) { + zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + if ((IS_CV & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + key = Z_REFVAL_P(key); + } + ZVAL_COPY(&generator->key, key); - UNDEF_RESULT(); - goto exit_assign_obj; + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); } + } else { + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_DEREF(value); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + ZEND_VM_RETURN(); +} -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *array; + zval *value, *variable_ptr; + uint32_t value_type; + HashTable *fe_ht; + HashPosition pos; + array = EX_VAR(opline->op1.var); + SAVE_OPLINE(); + fe_ht = Z_ARRVAL_P(array); + pos = Z_FE_POS_P(array); + if (HT_IS_PACKED(fe_ht)) { + value = fe_ht->arPacked + pos; + while (1) { + if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { + /* reached end of iteration */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); + } + value_type = Z_TYPE_INFO_P(value); + ZEND_ASSERT(value_type != IS_INDIRECT); + if (EXPECTED(value_type != IS_UNDEF)) { + break; + } + pos++; + value++; + } + Z_FE_POS_P(array) = pos + 1; + if (0) { + ZVAL_LONG(EX_VAR(opline->result.var), pos); + } + } else { + Bucket *p; -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); + p = fe_ht->arData + pos; + while (1) { + if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { + /* reached end of iteration */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); + } + pos++; + value = &p->val; + value_type = Z_TYPE_INFO_P(value); + ZEND_ASSERT(value_type != IS_INDIRECT); + if (EXPECTED(value_type != IS_UNDEF)) { + break; + } + p++; + } + Z_FE_POS_P(array) = pos; + if (0) { + if (!p->key) { + ZVAL_LONG(EX_VAR(opline->result.var), p->h); + } else { + ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); + } + } } - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + variable_ptr = EX_VAR(opline->op2.var); + zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; + zval *array; + zval *value, *variable_ptr; + uint32_t value_type; + HashTable *fe_ht; + HashPosition pos; + array = EX_VAR(opline->op1.var); SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + fe_ht = Z_ARRVAL_P(array); + pos = Z_FE_POS_P(array); + if (HT_IS_PACKED(fe_ht)) { + value = fe_ht->arPacked + pos; + while (1) { + if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { + /* reached end of iteration */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); + } + value_type = Z_TYPE_INFO_P(value); + ZEND_ASSERT(value_type != IS_INDIRECT); + if (EXPECTED(value_type != IS_UNDEF)) { + break; + } + pos++; + value++; + } + Z_FE_POS_P(array) = pos + 1; + if (1) { + ZVAL_LONG(EX_VAR(opline->result.var), pos); + } + } else { + Bucket *p; - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; + p = fe_ht->arData + pos; + while (1) { + if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { + /* reached end of iteration */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); + } + pos++; + value = &p->val; + value_type = Z_TYPE_INFO_P(value); + ZEND_ASSERT(value_type != IS_INDIRECT); + if (EXPECTED(value_type != IS_UNDEF)) { + break; + } + p++; + } + Z_FE_POS_P(array) = pos; + if (1) { + if (!p->key) { + ZVAL_LONG(EX_VAR(opline->result.var), p->h); + } else { + ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); + } } - zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; } -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; + variable_ptr = EX_VAR(opline->op2.var); + zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *obj; + zend_object *zobj; + zend_class_entry *ce, *scope; + zend_function *clone; + zend_object_clone_obj_t clone_call; - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_TMP_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_TMP_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_TMP_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; + SAVE_OPLINE(); + obj = &EX(This); + + /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. + * The OPcode intentionally does not support a clone-with property list to keep it simple. */ + + do { + if (IS_UNUSED == IS_CONST || + (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { + if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) { + obj = Z_REFVAL_P(obj); + if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) { + break; } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; + } + ZVAL_UNDEF(EX_VAR(opline->result.var)); + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); } - /* Fall through to write_property for hooks. */ } + zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj)); + + + HANDLE_EXCEPTION(); } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } + } while (0); - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_DEREF(value); - } + zobj = Z_OBJ_P(obj); + ce = zobj->ce; + clone = ce->clone; + clone_call = zobj->handlers->clone_obj; + if (UNEXPECTED(clone_call == NULL)) { + zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); + if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) { + scope = EX(func)->op_array.scope; + ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC)); + if (!zend_check_method_accessible(clone, scope)) { + zend_bad_method_call(clone, clone->common.function_name, scope); + + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } } + ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_NAME_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + uint32_t fetch_type; + zend_class_entry *called_scope, *scope; USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_UNUSED != IS_UNUSED) { + SAVE_OPLINE(); + zval *op = NULL; + if (UNEXPECTED(Z_TYPE_P(op) != IS_OBJECT)) { + ZVAL_DEREF(op); + if (Z_TYPE_P(op) != IS_OBJECT) { + zend_type_error("Cannot use \"::class\" on %s", zend_zval_value_name(op)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; + + HANDLE_EXCEPTION(); + } } - zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op)->name); - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + fetch_type = opline->op1.num; + scope = EX(func)->op_array.scope; + if (UNEXPECTED(scope == NULL)) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", + fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : + fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); + switch (fetch_type) { + case ZEND_FETCH_CLASS_SELF: + ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->name); + break; + case ZEND_FETCH_CLASS_PARENT: + if (UNEXPECTED(scope->parent == NULL)) { + SAVE_OPLINE(); + zend_throw_error(NULL, + "Cannot use \"parent\" when current class scope has no parent"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->parent->name); + break; + case ZEND_FETCH_CLASS_STATIC: + if (Z_TYPE(EX(This)) == IS_OBJECT) { + called_scope = Z_OBJCE(EX(This)); + } else { + called_scope = Z_CE(EX(This)); + } + ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name); + break; + EMPTY_SWITCH_DEFAULT_CASE() } - - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_NEXT_OPCODE(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; + zval *object; + zval *property; + zval *value; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; zend_object *zobj; zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } + object = &EX(This); + property = RT_CONSTANT(opline, opline->op2); -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; + do { + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_op_object; + } + if (IS_UNUSED == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } +assign_op_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + UNDEF_RESULT(); + break; + } + } + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); } + } else { + zend_reference *ref; - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CV != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CV == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_CV == IS_CV) { - Z_TRY_ADDREF_P(value); + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + zptr = Z_REFVAL_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; } } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; + + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + if (prop_info) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_binary_op(zptr, zptr, value OPLINE_CC); } - goto assign_obj_simple; + } while (0); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), zptr); } - /* Fall through to write_property for hooks. */ } + } else { + zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - - - UNDEF_RESULT(); - goto exit_assign_obj; + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } - } - - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + } while (0); -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + object = &EX(This); + property = RT_CONSTANT(opline, opline->op2); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_CV == IS_UNUSED) { - value = RT_CONSTANT((opline+1), (opline+1)->op1); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_DEREF(value); + do { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto pre_incdec_object; } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_CONST == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_CONST == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } + if (IS_UNUSED == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } + +pre_incdec_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(property); } else { - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + UNDEF_RESULT(); + break; } - value = RT_CONSTANT((opline+1), (opline+1)->op1); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); + zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } + } else { + zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = RT_CONSTANT((opline+1), (opline+1)->op1); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_CONST & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CV == IS_UNUSED) { - zend_use_new_element_for_string(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - UNDEF_RESULT(); - } else { - dim = EX_VAR(opline->op2.var); - value = RT_CONSTANT((opline+1), (opline+1)->op1); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; + SAVE_OPLINE(); + object = &EX(This); + property = RT_CONSTANT(opline, opline->op2); + do { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto post_incdec_object; } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - + if (IS_UNUSED == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } +post_incdec_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(property); } else { - zend_use_scalar_as_array(); - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); -assign_dim_error: - - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; + } + } + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } + } else { + zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); } - } - if (IS_CV != IS_UNUSED) { + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; + zval *container; + void **cache_slot = NULL; SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + container = &EX(This); + if (IS_UNUSED & (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 (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_CV == IS_UNUSED) { - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; + if (IS_UNUSED == IS_CONST || + (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if ((IS_UNUSED & IS_CV) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; } } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_DEREF(value); + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_TMP_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_TMP_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); + zend_wrong_property_read(container, RT_CONSTANT(opline, opline->op2)); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; + } while (0); + } + + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; + + if (IS_CONST == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); + + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_r_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { +fetch_obj_r_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + prop_offset = prop_info->offset; + goto fetch_obj_r_simple; + } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { + zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; + ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); + ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); + + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (IS_UNUSED & IS_CV) { + GC_ADDREF(zobj); + } + if (IS_UNUSED & (IS_CV|IS_VAR|IS_TMP_VAR)) { + call_info |= ZEND_CALL_RELEASE_THIS; + } + zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); + call->prev_execute_data = execute_data; + call->call = NULL; + call->return_value = EX_VAR(opline->result.var); + call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); + + execute_data = call; + EG(current_execute_data) = execute_data; + zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); + +#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) + opline = hook->op_array.opcodes; +#else + EX(opline) = hook->op_array.opcodes; +#endif + LOAD_OPLINE_EX(); + + + + + ZEND_VM_ENTER_EX(); + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); } } + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); } else { - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; } - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + +#if ZEND_DEBUG + /* For non-standard object handlers, verify a declared property type in debug builds. + * Fetch prop_info before calling read_property(), as it may deallocate the object. */ + zend_property_info *prop_info = NULL; + if (zobj->handlers->read_property != zend_std_read_property) { + prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); } - if (garbage) { - GC_DTOR_NO_REF(garbage); +#endif + retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO + && ZEND_TYPE_IS_SET(prop_info->type)) { + ZVAL_OPT_DEREF(retval); + zend_verify_property_type(prop_info, retval, /* strict */ true); } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } +#endif + + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_r_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } + } while (0); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } +fetch_obj_r_finish: - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CV == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = EX_VAR(opline->op2.var); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_CV != IS_UNUSED) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; + zval *property, *container, *result; SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_CV == IS_UNUSED) { - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - GC_ADDREF(obj); - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } + container = &EX(This); + property = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + zend_fetch_property_address( + result, container, IS_UNUSED, property, IS_CONST, + ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + if (IS_UNUSED == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CV == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = EX_VAR(opline->op2.var); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *property, *container, *result; - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_CV != IS_UNUSED) { + SAVE_OPLINE(); + container = &EX(This); + property = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + if (IS_UNUSED == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; + zval *container; + void **cache_slot = NULL; SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + container = &EX(This); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_CV == IS_UNUSED) { - value = EX_VAR((opline+1)->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); + if (IS_UNUSED == IS_CONST || + (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_CV == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_CV == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = EX_VAR((opline+1)->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_CV & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); + if (IS_CONST == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CV == IS_UNUSED) { - zend_use_new_element_for_string(); - + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; + } while (0); + } - UNDEF_RESULT(); - } else { - dim = EX_VAR(opline->op2.var); - value = EX_VAR((opline+1)->op1.var); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; + if (IS_CONST == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_is_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { +fetch_obj_is_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + goto fetch_obj_is_simple; + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } } } - goto try_assign_dim_array; } + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); } else { - zend_use_scalar_as_array(); - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); -assign_dim_error: - - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; } } - } - if (IS_CV != IS_UNUSED) { + retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *variable_ptr; + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_is_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } + } while (0); + +fetch_obj_is_finish: - SAVE_OPLINE(); - value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (0 || UNEXPECTED(0)) { - zend_refcounted *garbage = NULL; - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(0)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* zend_assign_to_variable() always takes care of op2, never free it! */ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { +#if 0 USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (0 || UNEXPECTED(1)) { - zend_refcounted *garbage = NULL; +#endif - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(1)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + /* Behave like FETCH_OBJ_W */ + if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - value = zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); + if (IS_UNUSED == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *variable_ptr; - zval *value_ptr; - zend_refcounted *garbage = NULL; + zval *container, *property, *result; SAVE_OPLINE(); - value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (IS_VAR == IS_VAR && - UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) { - - zend_throw_error(NULL, "Cannot assign by reference to an array dimension of an object"); - variable_ptr = &EG(uninitialized_zval); - } else if (IS_CV == IS_VAR && - opline->extended_value == ZEND_RETURNS_FUNCTION && - UNEXPECTED(!Z_ISREF_P(value_ptr))) { - - variable_ptr = zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_variable_reference(variable_ptr, value_ptr, &garbage); - } + container = &EX(This); + property = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr); - } - if (garbage) { - GC_DTOR(garbage); + if (IS_UNUSED == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } - - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *property, *container, *value_ptr; + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); + object = &EX(This); + value = RT_CONSTANT((opline+1), (opline+1)->op1); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; + } + zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } - value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - if (1) { - if (IS_VAR == IS_UNUSED) { - if (IS_CV == IS_CONST) { - zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } else { - if (IS_CV == IS_CONST) { - zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CONST != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CONST == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CONST == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } } else { - zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ } } + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); } else { - zend_assign_to_property_reference(container, IS_VAR, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + UNDEF_RESULT(); + goto exit_assign_obj; + } + } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_DEREF(value); + } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *property, *container, *value_ptr; + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - SAVE_OPLINE(); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } - value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); - if (1) { - if (IS_VAR == IS_UNUSED) { - if (IS_CV == IS_CONST) { - zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } else { - if (IS_CV == IS_CONST) { - zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } - } else { - zend_assign_to_property_reference(container, IS_VAR, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC); +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - + /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zend_class_entry *ce; - uint32_t call_info; - zend_function *fbc; - zend_execute_data *call; + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); + object = &EX(This); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CONST) { - /* no function found. try a static method in class */ - ce = CACHED_PTR(opline->result.num); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - - - HANDLE_EXCEPTION(); - } - if (IS_CV != IS_CONST) { - CACHE_PTR(opline->result.num, ce); - } + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; } - } else if (IS_VAR == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - + zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); - } +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - if (IS_VAR == IS_CONST && - IS_CV == IS_CONST && - EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { - /* nothing to do */ - } else if (IS_VAR != IS_CONST && - IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else if (IS_CV != IS_UNUSED) { - function_name = EX_VAR(opline->op2.var); - if (IS_CV != IS_CONST) { - if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if (IS_CV & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); } - } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); } + zobj->properties = zend_array_dup(zobj->properties); } - zend_throw_error(NULL, "Method name must be a string"); - + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } - HANDLE_EXCEPTION(); - } while (0); + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_TMP_VAR == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_TMP_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ } } - - if (ce->get_static_method) { - fbc = ce->get_static_method(ce, Z_STR_P(function_name)); - } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + } else { + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + if (UNEXPECTED(!name)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + goto exit_assign_obj; } - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(ce, Z_STR_P(function_name)); - } - + } - HANDLE_EXCEPTION(); - } - if (IS_CV == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { - CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - if (IS_CV != IS_CONST) { + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_DEREF(value); + } + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - } - } else { - if (UNEXPECTED(ce->constructor == NULL)) { - zend_throw_error(NULL, "Cannot call constructor"); - HANDLE_EXCEPTION(); - } - if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { - zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); - HANDLE_EXCEPTION(); - } - fbc = ce->constructor; - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } - if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { - if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - ce = (zend_class_entry*)Z_OBJ(EX(This)); - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - } else { - zend_non_static_method_call(fbc); - HANDLE_EXCEPTION(); - } - } else { - /* previous opcode is ZEND_FETCH_CLASS */ - if (IS_VAR == IS_UNUSED - && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { - if (Z_TYPE(EX(This)) == IS_OBJECT) { - ce = Z_OBJCE(EX(This)); - } else { - ce = Z_CE(EX(This)); - } - } - call_info = ZEND_CALL_NESTED_FUNCTION; +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); } - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, ce); - call->prev_execute_data = EX(call); - EX(call) = call; - ZEND_VM_NEXT_OPCODE(); + + + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *expr_ptr, new_expr; + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && - UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } else { - ZVAL_MAKE_REF_EX(expr_ptr, 2); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } else { - expr_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_TMP_VAR) { - /* pass */ - } else if (IS_VAR == IS_CONST) { - Z_TRY_ADDREF_P(expr_ptr); - } else if (IS_VAR == IS_CV) { - ZVAL_DEREF(expr_ptr); - Z_TRY_ADDREF_P(expr_ptr); - } else /* if (IS_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(expr_ptr); + object = &EX(This); + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - ZVAL_COPY_VALUE(&new_expr, expr_ptr); - expr_ptr = &new_expr; - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } - } + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; } + zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; } - if (IS_CV != IS_UNUSED) { - zval *offset = EX_VAR(opline->op2.var); - zend_string *str; - zend_ulong hval; +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; -add_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_CV != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index; + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CV != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CV == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CV == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ } -str_index: - zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index: - zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto add_again; - } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { - zval tmp; - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_COPY(&tmp, expr_ptr); - } - zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - /* A userland error handler can do funky things to the expression, so reset it */ - zval_ptr_dtor(expr_ptr); - ZVAL_COPY_VALUE(expr_ptr, &tmp); - } - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(expr_ptr); - HANDLE_EXCEPTION(); - } - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); - goto num_index; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - zend_use_resource_as_offset(offset); - hval = Z_RES_HANDLE_P(offset); - goto num_index; - } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else { - zend_illegal_array_offset_access(offset); - zval_ptr_dtor_nogc(expr_ptr); } + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + } else { + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + if (UNEXPECTED(!name)) { - } else { - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { - zend_cannot_add_element(); - zval_ptr_dtor_nogc(expr_ptr); + UNDEF_RESULT(); + goto exit_assign_obj; } } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_DEREF(value); + } + + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } + + +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + + + + + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zval *array; - uint32_t size; USE_OPLINE + zval *property, *container, *value_ptr; SAVE_OPLINE(); - array = EX_VAR(opline->result.var); - if (IS_VAR != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + + container = &EX(This); + property = RT_CONSTANT(opline, opline->op2); + + value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + + if (1) { + if (IS_UNUSED == IS_UNUSED) { + if (IS_CONST == IS_CONST) { + zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } + } else { + if (IS_CONST == IS_CONST) { + zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZVAL_ARR(array, zend_new_array(0)); - ZEND_VM_NEXT_OPCODE(); + zend_assign_to_property_reference(container, IS_UNUSED, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); } + + + + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - zval *offset; - zend_ulong hval; - zend_string *key; + zval *property, *container, *value_ptr; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = EX_VAR(opline->op2.var); - do { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; + container = &EX(This); + property = RT_CONSTANT(opline, opline->op2); -unset_dim_array: - SEPARATE_ARRAY(container); - ht = Z_ARRVAL_P(container); -offset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - key = Z_STR_P(offset); - if (IS_CV != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(key, hval)) { - goto num_index_dim; - } - } -str_index_dim: - ZEND_ASSERT(ht != &EG(symbol_table)); - zend_hash_del(ht, key); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_dim: - zend_hash_index_del(ht, hval); - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto offset_again; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - /* The array may be destroyed while throwing a warning in case the float is not representable as an int. - * Temporarily increase the refcount to detect this situation. */ - GC_TRY_ADDREF(ht); - hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - break; - } - if (EG(exception)) { - break; - } - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_NULL) { - key = ZSTR_EMPTY_ALLOC(); - goto str_index_dim; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - zend_use_resource_as_offset(offset); - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - key = ZSTR_EMPTY_ALLOC(); - goto str_index_dim; + value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); + + if (1) { + if (IS_UNUSED == IS_UNUSED) { + if (IS_CONST == IS_CONST) { + zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { - zend_illegal_array_offset_unset(offset); + zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } - break; - } else if (Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto unset_dim_array; + } else { + if (IS_CONST == IS_CONST) { + zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - container = ZVAL_UNDEFINED_OP1(); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { - offset = ZVAL_UNDEFINED_OP2(); + } else { + zend_assign_to_property_reference(container, IS_UNUSED, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } + + + + + + + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_INIT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_string **rope; + zval *var; + + /* Compiler allocates the necessary number of zval slots to keep the rope */ + rope = (zend_string**)EX_VAR(opline->result.var); + if (IS_CONST == IS_CONST) { + var = RT_CONSTANT(opline, opline->op2); + rope[0] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); } - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; + } else { + var = RT_CONSTANT(opline, opline->op2); + if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { + if (IS_CONST == IS_CV) { + rope[0] = zend_string_copy(Z_STR_P(var)); + } else { + rope[0] = Z_STR_P(var); } - Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset); - } else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - } else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) { - zend_throw_error(NULL, "Cannot unset offset in a non-array variable"); - } else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) { - zend_false_to_array_deprecated(); - } - } while (0); + } else { + SAVE_OPLINE(); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + } + rope[0] = zval_get_string_func(var); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zval *class_name; USE_OPLINE - zval *container; - zval *offset; - zend_string *name, *tmp_name; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + if (IS_CONST == IS_UNUSED) { + Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else if (IS_CONST == IS_CONST) { + zend_class_entry *ce = CACHED_PTR(opline->extended_value); - do { - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - if (Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (Z_TYPE_P(container) != IS_OBJECT) { - if (IS_VAR == IS_CV - && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - break; - } - } else { - break; - } + if (UNEXPECTED(ce == NULL)) { + class_name = RT_CONSTANT(opline, opline->op2); + ce = zend_fetch_class_by_name(Z_STR_P(class_name), Z_STR_P(class_name + 1), opline->op1.num); + CACHE_PTR(opline->extended_value, ce); } - if (IS_CV == IS_CONST) { - name = Z_STR_P(offset); + Z_CE_P(EX_VAR(opline->result.var)) = ce; + } else { + class_name = RT_CONSTANT(opline, opline->op2); +try_class_name: + if (Z_TYPE_P(class_name) == IS_OBJECT) { + Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name); + } else if (Z_TYPE_P(class_name) == IS_STRING) { + Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) { + class_name = Z_REFVAL_P(class_name); + goto try_class_name; } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - break; + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } + zend_throw_error(NULL, "Class name must be a valid object or a string"); } - Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - } while (0); + } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + zval *function_name; + zval *object; + zend_function *fbc; + zend_class_entry *called_scope; + zend_object *obj; + zend_execute_data *call; + uint32_t call_info; SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); + object = &EX(This); - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); + if (IS_CONST != IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } - /* Set the new yielded value */ - if (IS_VAR != IS_UNUSED) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_VAR & (IS_CONST|IS_TMP_VAR)) { - zval *value; + if (IS_CONST != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } + HANDLE_EXCEPTION(); } + } + zend_throw_error(NULL, "Method name must be a string"); + + + + + HANDLE_EXCEPTION(); + } while (0); + } + + if (IS_UNUSED == IS_UNUSED) { + obj = Z_OBJ_P(object); + } else { + do { + if (IS_UNUSED != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); } else { - zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + zend_reference *ref = Z_REF_P(object); - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - do { - if (IS_VAR == IS_VAR) { - ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION - && !Z_ISREF_P(value_ptr)) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - ZVAL_COPY(&generator->value, value_ptr); - break; + object = &ref->val; + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + if (IS_UNUSED & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } } + break; } - if (Z_ISREF_P(value_ptr)) { - Z_ADDREF_P(value_ptr); - } else { - ZVAL_MAKE_REF_EX(value_ptr, 2); - } - ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); - } while (0); + } + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + object = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_CONST != IS_CONST) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } - } else { - zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - /* Consts, temporary variables and references need copying */ - if (IS_VAR == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); + } + HANDLE_EXCEPTION(); + } } - } else if (IS_VAR == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); } - } - } - } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); - } + zend_invalid_method_call(object, function_name); - /* Set the new yielded key */ - if (IS_CV != IS_UNUSED) { - zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if ((IS_CV & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { - key = Z_REFVAL_P(key); - } - ZVAL_COPY(&generator->key, key); - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); - } - } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); - } - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); - } else { - generator->send_target = NULL; + HANDLE_EXCEPTION(); + } + } while (0); } - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); + called_scope = obj->ce; - ZEND_VM_RETURN(); -} + if (IS_CONST == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else { + zend_object *orig_obj = obj; -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *array; - zval *value, *variable_ptr; - uint32_t value_type; - HashTable *fe_ht; - HashPosition pos; + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } - array = EX_VAR(opline->op1.var); - SAVE_OPLINE(); - fe_ht = Z_ARRVAL_P(array); - pos = Z_FE_POS_P(array); - if (HT_IS_PACKED(fe_ht)) { - value = fe_ht->arPacked + pos; - while (1) { - if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { - /* reached end of iteration */ - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); + /* First, locate the function. */ + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); } - value_type = Z_TYPE_INFO_P(value); - ZEND_ASSERT(value_type != IS_INDIRECT); - if (EXPECTED(value_type != IS_UNDEF)) { - break; + + + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); } - pos++; - value++; + HANDLE_EXCEPTION(); } - Z_FE_POS_P(array) = pos + 1; - if (0) { - ZVAL_LONG(EX_VAR(opline->result.var), pos); + if (IS_CONST == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(obj == orig_obj)) { + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } - } else { - Bucket *p; - - p = fe_ht->arData + pos; - while (1) { - if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { - /* reached end of iteration */ - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } - pos++; - value = &p->val; - value_type = Z_TYPE_INFO_P(value); - ZEND_ASSERT(value_type != IS_INDIRECT); - if (EXPECTED(value_type != IS_UNDEF)) { - break; + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); } - p++; } - Z_FE_POS_P(array) = pos; - if (0) { - if (!p->key) { - ZVAL_LONG(EX_VAR(opline->result.var), p->h); - } else { - ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); - } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); } } - variable_ptr = EX_VAR(opline->op2.var); - zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - + if (IS_CONST != IS_CONST) { -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *array; - zval *value, *variable_ptr; - uint32_t value_type; - HashTable *fe_ht; - HashPosition pos; - array = EX_VAR(opline->op1.var); - SAVE_OPLINE(); - fe_ht = Z_ARRVAL_P(array); - pos = Z_FE_POS_P(array); - if (HT_IS_PACKED(fe_ht)) { - value = fe_ht->arPacked + pos; - while (1) { - if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { - /* reached end of iteration */ - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } - value_type = Z_TYPE_INFO_P(value); - ZEND_ASSERT(value_type != IS_INDIRECT); - if (EXPECTED(value_type != IS_UNDEF)) { - break; - } - pos++; - value++; - } - Z_FE_POS_P(array) = pos + 1; - if (1) { - ZVAL_LONG(EX_VAR(opline->result.var), pos); - } - } else { - Bucket *p; + } - p = fe_ht->arData + pos; - while (1) { - if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { - /* reached end of iteration */ - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } - pos++; - value = &p->val; - value_type = Z_TYPE_INFO_P(value); - ZEND_ASSERT(value_type != IS_INDIRECT); - if (EXPECTED(value_type != IS_UNDEF)) { - break; + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); } - p++; } - Z_FE_POS_P(array) = pos; - if (1) { - if (!p->key) { - ZVAL_LONG(EX_VAR(opline->result.var), p->h); - } else { - ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); - } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; + } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { + if (IS_UNUSED == IS_CV) { + GC_ADDREF(obj); /* For $this pointer */ } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } - variable_ptr = EX_VAR(opline->op2.var); - zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, obj); + call->prev_execute_data = EX(call); + EX(call) = call; + ZEND_VM_NEXT_OPCODE(); +} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *obj; - zend_object *zobj; - zend_class_entry *ce, *scope; - zend_function *clone; - zend_object_clone_obj_t clone_call; + zval *function_name; + zend_class_entry *ce; + uint32_t call_info; + zend_function *fbc; + zend_execute_data *call; SAVE_OPLINE(); - obj = &EX(This); - /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. - * The OPcode intentionally does not support a clone-with property list to keep it simple. */ + if (IS_UNUSED == IS_CONST) { + /* no function found. try a static method in class */ + ce = CACHED_PTR(opline->result.num); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { - do { - if (IS_UNUSED == IS_CONST || - (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) { - obj = Z_REFVAL_P(obj); - if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) { - break; - } + + HANDLE_EXCEPTION(); } - ZVAL_UNDEF(EX_VAR(opline->result.var)); - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_CONST != IS_CONST) { + CACHE_PTR(opline->result.num, ce); + } + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + + + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + + if (IS_UNUSED == IS_CONST && + IS_CONST == IS_CONST && + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { + /* nothing to do */ + } else if (IS_UNUSED != IS_CONST && + IS_CONST == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else if (IS_CONST != IS_UNUSED) { + function_name = RT_CONSTANT(opline, opline->op2); + if (IS_CONST != IS_CONST) { + if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if (IS_CONST & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Method name must be a string"); + + HANDLE_EXCEPTION(); - } + } while (0); + } + } + + if (ce->get_static_method) { + fbc = ce->get_static_method(ce, Z_STR_P(function_name)); + } else { + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + } + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(ce, Z_STR_P(function_name)); } - zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj)); HANDLE_EXCEPTION(); } - } while (0); + if (IS_CONST == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + if (IS_CONST != IS_CONST) { - zobj = Z_OBJ_P(obj); - ce = zobj->ce; - clone = ce->clone; - clone_call = zobj->handlers->clone_obj; - if (UNEXPECTED(clone_call == NULL)) { - zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); + } + } else { + if (UNEXPECTED(ce->constructor == NULL)) { + zend_throw_error(NULL, "Cannot call constructor"); + HANDLE_EXCEPTION(); + } + if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { + zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); + HANDLE_EXCEPTION(); + } + fbc = ce->constructor; + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + } - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + } else { + zend_non_static_method_call(fbc); + HANDLE_EXCEPTION(); + } + } else { + /* previous opcode is ZEND_FETCH_CLASS */ + if (IS_UNUSED == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { + if (Z_TYPE(EX(This)) == IS_OBJECT) { + ce = Z_OBJCE(EX(This)); + } else { + ce = Z_CE(EX(This)); + } + } + call_info = ZEND_CALL_NESTED_FUNCTION; } - if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) { - scope = EX(func)->op_array.scope; - ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC)); - if (!zend_check_method_accessible(clone, scope)) { - zend_bad_method_call(clone, clone->common.function_name, scope); + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); + call->prev_execute_data = EX(call); + EX(call) = call; + ZEND_VM_NEXT_OPCODE(); +} - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + uint32_t arg_num; + + if (IS_CONST == IS_CONST) { + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + arg_num = zend_get_arg_offset_by_name( + EX(call)->func, arg_name, CACHE_ADDR(opline->result.num)) + 1; + if (UNEXPECTED(arg_num == 0)) { + /* Treat this as a by-value argument, and throw an error during SEND. */ + ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); + ZEND_VM_NEXT_OPCODE(); } + } else { + arg_num = opline->op2.num; } - ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj)); + if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) { + if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); + } else { + ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); + } + } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); + } else { + ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_constant *c; + c = CACHED_PTR(opline->extended_value); + if (EXPECTED(c != NULL) && EXPECTED(!IS_SPECIAL_CACHE_VAL(c))) { + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); + ZEND_VM_NEXT_OPCODE(); + } + SAVE_OPLINE(); + zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num OPLINE_CC EXECUTE_DATA_CC); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_NAME_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - uint32_t fetch_type; - zend_class_entry *called_scope, *scope; + zend_class_entry *ce, *scope; + zend_class_constant *c; + zval *value, *zv, *constant_zv; + zend_string *constant_name; USE_OPLINE - if (IS_UNUSED != IS_UNUSED) { - SAVE_OPLINE(); - zval *op = NULL; - if (UNEXPECTED(Z_TYPE_P(op) != IS_OBJECT)) { - ZVAL_DEREF(op); - if (Z_TYPE_P(op) != IS_OBJECT) { - zend_type_error("Cannot use \"::class\" on %s", zend_zval_value_name(op)); + SAVE_OPLINE(); + + do { + if (IS_UNUSED == IS_CONST && IS_CONST == IS_CONST) { + if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); + break; + } + } + if (IS_UNUSED == IS_CONST) { + if (EXPECTED(CACHED_PTR(opline->extended_value))) { + ce = CACHED_PTR(opline->extended_value); + } else { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + + + HANDLE_EXCEPTION(); + } + CACHE_PTR(opline->extended_value, ce); + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + if (IS_UNUSED != IS_CONST + && IS_CONST == IS_CONST + && EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); + break; } - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op)->name); + constant_zv = RT_CONSTANT(opline, opline->op2); + if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) { + zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } + HANDLE_EXCEPTION(); + } + constant_name = Z_STR_P(constant_zv); + /* Magic 'class' for constant OP2 is caught at compile-time */ + if (IS_CONST != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); - fetch_type = opline->op1.num; - scope = EX(func)->op_array.scope; - if (UNEXPECTED(scope == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", - fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : - fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - switch (fetch_type) { - case ZEND_FETCH_CLASS_SELF: - ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->name); - break; - case ZEND_FETCH_CLASS_PARENT: - if (UNEXPECTED(scope->parent == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, - "Cannot use \"parent\" when current class scope has no parent"); + ZEND_VM_NEXT_OPCODE(); + } + zv = IS_CONST == IS_CONST + ? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name) + : zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name); + + if (EXPECTED(zv != NULL)) { + c = Z_PTR_P(zv); + scope = EX(func)->op_array.scope; + if (!zend_verify_const_access(c, scope)) { + zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); ZVAL_UNDEF(EX_VAR(opline->result.var)); + + HANDLE_EXCEPTION(); } - ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->parent->name); - break; - case ZEND_FETCH_CLASS_STATIC: - if (Z_TYPE(EX(This)) == IS_OBJECT) { - called_scope = Z_OBJCE(EX(This)); - } else { - called_scope = Z_CE(EX(This)); + + if (ce->ce_flags & ZEND_ACC_TRAIT) { + zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + + + HANDLE_EXCEPTION(); } - ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object; - zval *property; - zval *value; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; + bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; + if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) { + if (c->ce->type == ZEND_USER_CLASS) { + /* Recursion protection only applied to user constants, GH-18463 */ + CONST_PROTECT_RECURSION(c); + } + zend_deprecated_class_constant(c, constant_name); + if (c->ce->type == ZEND_USER_CLASS) { + CONST_UNPROTECT_RECURSION(c); + } - SAVE_OPLINE(); - object = &EX(This); - property = RT_CONSTANT(opline, opline->op2); + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); - do { - value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_op_object; - } - if (IS_UNUSED == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + HANDLE_EXCEPTION(); + } } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; - } -assign_op_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - UNDEF_RESULT(); - break; - } - } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - zend_reference *ref; + value = &c->value; + // Enums require loading of all class constants to build the backed enum table + if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { + if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); - do { - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - zptr = Z_REFVAL_P(zptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - if (prop_info) { - /* special case for typed properties */ - zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_binary_op(zptr, zptr, value OPLINE_CC); - } - } while (0); + HANDLE_EXCEPTION(); + } + } + if (Z_TYPE_P(value) == IS_CONSTANT_AST) { + if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), zptr); + + HANDLE_EXCEPTION(); } } + if (IS_CONST == IS_CONST && !is_constant_deprecated) { + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); + } } else { - zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); - } - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); + zend_throw_error(NULL, "Undefined constant %s::%s", + ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + + + HANDLE_EXCEPTION(); } } while (0); - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); + ZEND_VM_NEXT_OPCODE(); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zval *array; + uint32_t size; + USE_OPLINE - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + SAVE_OPLINE(); + array = EX_VAR(opline->result.var); + if (IS_UNUSED != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + } + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_ARR(array, zend_new_array(0)); + ZEND_VM_NEXT_OPCODE(); + } } -/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; + zval *container; + zval *offset; zend_string *name, *tmp_name; SAVE_OPLINE(); - object = &EX(This); - property = RT_CONSTANT(opline, opline->op2); + container = &EX(This); + offset = RT_CONSTANT(opline, opline->op2); do { - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto pre_incdec_object; - } - if (IS_UNUSED == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + if (IS_UNUSED == IS_CV + && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + break; + } + } else { + break; } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; } - -pre_incdec_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - name = Z_STR_P(property); + name = Z_STR_P(offset); } else { - name = zval_try_get_tmp_string(property, &tmp_name); + name = zval_try_get_tmp_string(offset, &tmp_name); if (UNEXPECTED(!name)) { - UNDEF_RESULT(); break; } } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); - } - } else { - zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); - } + Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -34535,30 +34758,497 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_S ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; + zval *container; + int result; + zval *offset; zend_string *name, *tmp_name; SAVE_OPLINE(); - object = &EX(This); - property = RT_CONSTANT(opline, opline->op2); + container = &EX(This); + offset = RT_CONSTANT(opline, opline->op2); - do { - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto post_incdec_object; - } - if (IS_UNUSED == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + if (IS_UNUSED == IS_CONST || + (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } + } else { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } + } + + if (IS_CONST == IS_CONST) { + name = Z_STR_P(offset); + } else { + name = zval_try_get_tmp_string(offset, &tmp_name); + if (UNEXPECTED(!name)) { + result = 0; + goto isset_object_finish; + } + } + + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + +isset_object_finish: + + + + + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + + SAVE_OPLINE(); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); + + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); + + /* Set the new yielded value */ + if (IS_UNUSED != IS_UNUSED) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_UNUSED & (IS_CONST|IS_TMP_VAR)) { + zval *value; + + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + + value = NULL; + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_UNUSED == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } + } else { + zval *value_ptr = NULL; + + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + do { + if (IS_UNUSED == IS_VAR) { + ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION + && !Z_ISREF_P(value_ptr)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + ZVAL_COPY(&generator->value, value_ptr); + break; + } + } + if (Z_ISREF_P(value_ptr)) { + Z_ADDREF_P(value_ptr); + } else { + ZVAL_MAKE_REF_EX(value_ptr, 2); + } + ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); + } while (0); + + + } + } else { + zval *value = NULL; + + /* Consts, temporary variables and references need copying */ + if (IS_UNUSED == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } else if (IS_UNUSED == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + + + } else { + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_UNUSED == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } + } + } + } else { + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); + } + + /* Set the new yielded key */ + if (IS_CONST != IS_UNUSED) { + zval *key = RT_CONSTANT(opline, opline->op2); + if ((IS_CONST & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + key = Z_REFVAL_P(key); + } + ZVAL_COPY(&generator->key, key); + + + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); + } + } else { + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); + } + + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; + } + + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); + + ZEND_VM_RETURN(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zend_class_entry *ce, *scope; + zend_class_constant *c; + zval *value, *zv, *constant_zv; + zend_string *constant_name; + USE_OPLINE + + SAVE_OPLINE(); + + do { + if (IS_UNUSED == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); + break; + } + } + if (IS_UNUSED == IS_CONST) { + if (EXPECTED(CACHED_PTR(opline->extended_value))) { + ce = CACHED_PTR(opline->extended_value); + } else { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } + CACHE_PTR(opline->extended_value, ce); + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + if (IS_UNUSED != IS_CONST + && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST + && EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); + break; + } + + constant_zv = _get_zval_ptr_tmpvarcv(opline->op2_type, opline->op2, BP_VAR_R EXECUTE_DATA_CC); + if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) { + zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } + constant_name = Z_STR_P(constant_zv); + /* Magic 'class' for constant OP2 is caught at compile-time */ + if ((IS_TMP_VAR|IS_VAR|IS_CV) != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); + FREE_OP(opline->op2_type, opline->op2.var); + ZEND_VM_NEXT_OPCODE(); + } + zv = (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST + ? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name) + : zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name); + + if (EXPECTED(zv != NULL)) { + c = Z_PTR_P(zv); + scope = EX(func)->op_array.scope; + if (!zend_verify_const_access(c, scope)) { + zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } + + if (ce->ce_flags & ZEND_ACC_TRAIT) { + zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } + + bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; + if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) { + if (c->ce->type == ZEND_USER_CLASS) { + /* Recursion protection only applied to user constants, GH-18463 */ + CONST_PROTECT_RECURSION(c); + } + zend_deprecated_class_constant(c, constant_name); + if (c->ce->type == ZEND_USER_CLASS) { + CONST_UNPROTECT_RECURSION(c); + } + + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } + } + + value = &c->value; + // Enums require loading of all class constants to build the backed enum table + if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { + if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } + } + if (Z_TYPE_P(value) == IS_CONSTANT_AST) { + if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } + } + if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && !is_constant_deprecated) { + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); + } + } else { + zend_throw_error(NULL, "Undefined constant %s::%s", + ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } + } while (0); + + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); + + FREE_OP(opline->op2_type, opline->op2.var); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *object; + zval *property; + zval *value; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; + + SAVE_OPLINE(); + object = &EX(This); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + do { + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); + + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_op_object; + } + if (IS_UNUSED == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } + +assign_op_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_TMP_VAR == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + UNDEF_RESULT(); + break; + } + } + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + zend_reference *ref; + + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + zptr = Z_REFVAL_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; + } + } + + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + if (prop_info) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_binary_op(zptr, zptr, value OPLINE_CC); + } + } while (0); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), zptr); + } + } + } else { + zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); + } + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); + + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; + + SAVE_OPLINE(); + object = &EX(This); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + do { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto pre_incdec_object; + } + if (IS_UNUSED == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } + +pre_incdec_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_TMP_VAR == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + UNDEF_RESULT(); + break; + } + } + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); + zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); + } + } else { + zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); + } + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); + + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; + + SAVE_OPLINE(); + object = &EX(This); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + do { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto post_incdec_object; + } + if (IS_UNUSED == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); @@ -34568,7 +35258,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_ post_incdec_object: /* here we are sure we are dealing with an object */ zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(property); } else { name = zval_try_get_tmp_string(property, &tmp_name); @@ -34577,7 +35267,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_ break; } } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -34588,18 +35278,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_ } else { zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); } - if (IS_CONST != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } } while (0); - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -34607,11 +35297,15 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV SAVE_OPLINE(); container = &EX(This); + if (IS_UNUSED & (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 (IS_UNUSED == IS_CONST || (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { do { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + if ((IS_UNUSED & IS_CV) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; @@ -34620,7 +35314,7 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - zend_wrong_property_read(container, RT_CONSTANT(opline, opline->op2)); + zend_wrong_property_read(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); ZVAL_NULL(EX_VAR(opline->result.var)); goto fetch_obj_r_finish; } while (0); @@ -34632,7 +35326,7 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_string *name, *tmp_name; zval *retval; - if (IS_CONST == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { @@ -34692,7 +35386,7 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV /* Fall through to read_property for hooks. */ } else if (EXPECTED(zobj->properties != NULL)) { ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); @@ -34725,9 +35419,9 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV } } } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); break; @@ -34751,7 +35445,7 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV } #endif - if (IS_CONST != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -34764,19 +35458,13 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV } while (0); fetch_obj_r_finish: - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *property, *container, *result; @@ -34784,39 +35472,37 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_S SAVE_OPLINE(); container = &EX(This); - property = RT_CONSTANT(opline, opline->op2); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); zend_fetch_property_address( - result, container, IS_UNUSED, property, IS_CONST, - ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), + result, container, IS_UNUSED, property, IS_TMP_VAR, + ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *property, *container, *result; SAVE_OPLINE(); container = &EX(This); - property = RT_CONSTANT(opline, opline->op2); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - - + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -34824,6 +35510,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_ SAVE_OPLINE(); container = &EX(This); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ if (IS_UNUSED == IS_CONST || (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -34834,7 +35522,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_ break; } } - if (IS_CONST == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { + if (IS_TMP_VAR == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); } ZVAL_NULL(EX_VAR(opline->result.var)); @@ -34848,7 +35536,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_ zend_string *name, *tmp_name; zval *retval; - if (IS_CONST == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { @@ -34875,7 +35563,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_ /* Fall through to read_property for hooks. */ } else if (EXPECTED(zobj->properties != NULL)) { ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); @@ -34908,9 +35596,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_ } } } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); break; @@ -34919,7 +35607,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_ retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - if (IS_CONST != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -34932,14 +35620,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_ } while (0); fetch_obj_is_finish: - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 USE_OPLINE @@ -34950,31 +35637,42 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUN if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) { ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_UNUSED == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container, *property, *result; SAVE_OPLINE(); container = &EX(This); - property = RT_CONSTANT(opline, opline->op2); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - - + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object, *value, tmp; @@ -34991,14 +35689,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP object = Z_REFVAL_P(object); goto assign_object; } - zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); value = &EG(uninitialized_zval); goto free_and_exit_assign_obj; } assign_object: zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -35024,7 +35722,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP } } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { zobj = zend_lazy_object_init(zobj); if (!zobj) { @@ -35092,9 +35790,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP /* Fall through to write_property for hooks. */ } } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { @@ -35107,9 +35805,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if (IS_CONST != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -35123,16 +35821,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP if (garbage) { GC_DTOR_NO_REF(garbage); } - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object, *value, tmp; @@ -35149,14 +35846,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP object = Z_REFVAL_P(object); goto assign_object; } - zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); value = &EG(uninitialized_zval); goto free_and_exit_assign_obj; } assign_object: zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -35182,7 +35879,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP } } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { zobj = zend_lazy_object_init(zobj); if (!zobj) { @@ -35250,9 +35947,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP /* Fall through to write_property for hooks. */ } } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); @@ -35264,9 +35961,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if (IS_CONST != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -35279,172 +35976,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP if (garbage) { GC_DTOR_NO_REF(garbage); } - - - - - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = &EX(This); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object, *value, tmp; @@ -35461,14 +36001,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP object = Z_REFVAL_P(object); goto assign_object; } - zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); value = &EG(uninitialized_zval); goto free_and_exit_assign_obj; } assign_object: zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -35494,7 +36034,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP } } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { zobj = zend_lazy_object_init(zobj); if (!zobj) { @@ -35562,9 +36102,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP /* Fall through to write_property for hooks. */ } } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { @@ -35577,9 +36117,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if (IS_CONST != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -35593,16 +36133,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SP if (garbage) { GC_DTOR_NO_REF(garbage); } - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *property, *container, *value_ptr; @@ -35610,37 +36149,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_RE SAVE_OPLINE(); container = &EX(This); - property = RT_CONSTANT(opline, opline->op2); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); if (1) { if (IS_UNUSED == IS_UNUSED) { - if (IS_CONST == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } else { - if (IS_CONST == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } } else { - zend_assign_to_property_reference(container, IS_UNUSED, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_property_reference(container, IS_UNUSED, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); } - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *property, *container, *value_ptr; @@ -35648,38 +36186,37 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_RE SAVE_OPLINE(); container = &EX(This); - property = RT_CONSTANT(opline, opline->op2); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); if (1) { if (IS_UNUSED == IS_UNUSED) { - if (IS_CONST == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } else { - if (IS_CONST == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } } else { - zend_assign_to_property_reference(container, IS_UNUSED, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_property_reference(container, IS_UNUSED, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); } - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_INIT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_INIT_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_string **rope; @@ -35687,64 +36224,63 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_INIT_SPE /* Compiler allocates the necessary number of zval slots to keep the rope */ rope = (zend_string**)EX_VAR(opline->result.var); - if (IS_CONST == IS_CONST) { - var = RT_CONSTANT(opline, opline->op2); + if (IS_TMP_VAR == IS_CONST) { + var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); rope[0] = Z_STR_P(var); if (UNEXPECTED(Z_REFCOUNTED_P(var))) { Z_ADDREF_P(var); } } else { - var = RT_CONSTANT(opline, opline->op2); + var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { - if (IS_CONST == IS_CV) { + if (IS_TMP_VAR == IS_CV) { rope[0] = zend_string_copy(Z_STR_P(var)); } else { rope[0] = Z_STR_P(var); } } else { SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); } rope[0] = zval_get_string_func(var); - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } } ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *class_name; USE_OPLINE SAVE_OPLINE(); - if (IS_CONST == IS_UNUSED) { + if (IS_TMP_VAR == IS_UNUSED) { Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else if (IS_CONST == IS_CONST) { + } else if (IS_TMP_VAR == IS_CONST) { zend_class_entry *ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { - class_name = RT_CONSTANT(opline, opline->op2); + class_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); ce = zend_fetch_class_by_name(Z_STR_P(class_name), Z_STR_P(class_name + 1), opline->op1.num); CACHE_PTR(opline->extended_value, ce); } Z_CE_P(EX_VAR(opline->result.var)) = ce; } else { - class_name = RT_CONSTANT(opline, opline->op2); + class_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); try_class_name: if (Z_TYPE_P(class_name) == IS_OBJECT) { Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name); } else if (Z_TYPE_P(class_name) == IS_STRING) { Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) { + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) { class_name = Z_REFVAL_P(class_name); goto try_class_name; } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -35754,11 +36290,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_S } } - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; @@ -35773,19 +36309,19 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_I object = &EX(This); - if (IS_CONST != IS_CONST) { - function_name = RT_CONSTANT(opline, opline->op2); + if (IS_TMP_VAR != IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); } - if (IS_CONST != IS_CONST && + if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); if (UNEXPECTED(EG(exception) != NULL)) { @@ -35794,8 +36330,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_I } } zend_throw_error(NULL, "Method name must be a string"); - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); @@ -35828,19 +36363,17 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_I if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { object = ZVAL_UNDEFINED_OP1(); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CONST != IS_CONST) { - - + if (IS_TMP_VAR != IS_CONST) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } HANDLE_EXCEPTION(); } } - if (IS_CONST == IS_CONST) { - function_name = RT_CONSTANT(opline, opline->op2); + if (IS_TMP_VAR == IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); } zend_invalid_method_call(object, function_name); - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); @@ -35850,30 +36383,29 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_I called_scope = obj->ce; - if (IS_CONST == IS_CONST && + if (IS_TMP_VAR == IS_CONST && EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; - if (IS_CONST == IS_CONST) { - function_name = RT_CONSTANT(opline, opline->op2); + if (IS_TMP_VAR == IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); } /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); } - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } HANDLE_EXCEPTION(); } - if (IS_CONST == IS_CONST && + if (IS_TMP_VAR == IS_CONST && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); @@ -35889,9 +36421,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_I } } - if (IS_CONST != IS_CONST) { - - + if (IS_TMP_VAR != IS_CONST) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; @@ -35921,7 +36452,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_I ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; @@ -35938,19 +36469,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if (IS_CONST != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { CACHE_PTR(opline->result.num, ce); } } } else if (IS_UNUSED == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); if (UNEXPECTED(ce == NULL)) { - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } } else { @@ -35958,32 +36487,31 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M } if (IS_UNUSED == IS_CONST && - IS_CONST == IS_CONST && + IS_TMP_VAR == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_UNUSED != IS_CONST && - IS_CONST == IS_CONST && + IS_TMP_VAR == IS_CONST && EXPECTED(CACHED_PTR(opline->result.num) == ce)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else if (IS_CONST != IS_UNUSED) { - function_name = RT_CONSTANT(opline, opline->op2); - if (IS_CONST != IS_CONST) { + } else if (IS_TMP_VAR != IS_UNUSED) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR != IS_CONST) { if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if (IS_CONST & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + if (IS_TMP_VAR & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } } zend_throw_error(NULL, "Method name must be a string"); - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } while (0); } @@ -35992,17 +36520,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_undefined_method(ce, Z_STR_P(function_name)); } - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if (IS_CONST == IS_CONST && + if (IS_TMP_VAR == IS_CONST && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); @@ -36010,9 +36537,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } - if (IS_CONST != IS_CONST) { - - + if (IS_TMP_VAR != IS_CONST) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } } else { if (UNEXPECTED(ce->constructor == NULL)) { @@ -36059,198 +36585,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - uint32_t arg_num; - - if (IS_CONST == IS_CONST) { - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - arg_num = zend_get_arg_offset_by_name( - EX(call)->func, arg_name, CACHE_ADDR(opline->result.num)) + 1; - if (UNEXPECTED(arg_num == 0)) { - /* Treat this as a by-value argument, and throw an error during SEND. */ - ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); - ZEND_VM_NEXT_OPCODE(); - } - } else { - arg_num = opline->op2.num; - } - - if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) { - if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); - } else { - ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); - } - } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); - } else { - ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_constant *c; - - c = CACHED_PTR(opline->extended_value); - if (EXPECTED(c != NULL) && EXPECTED(!IS_SPECIAL_CACHE_VAL(c))) { - ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - zend_quick_get_constant(RT_CONSTANT(opline, opline->op2) + 1, opline->op1.num OPLINE_CC EXECUTE_DATA_CC); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zend_class_entry *ce, *scope; - zend_class_constant *c; - zval *value, *zv, *constant_zv; - zend_string *constant_name; - USE_OPLINE - - SAVE_OPLINE(); - - do { - if (IS_UNUSED == IS_CONST && IS_CONST == IS_CONST) { - if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) { - value = CACHED_PTR(opline->extended_value + sizeof(void*)); - break; - } - } - if (IS_UNUSED == IS_CONST) { - if (EXPECTED(CACHED_PTR(opline->extended_value))) { - ce = CACHED_PTR(opline->extended_value); - } else { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - - - HANDLE_EXCEPTION(); - } - CACHE_PTR(opline->extended_value, ce); - } - } else if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - - - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - if (IS_UNUSED != IS_CONST - && IS_CONST == IS_CONST - && EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { - value = CACHED_PTR(opline->extended_value + sizeof(void*)); - break; - } - - constant_zv = RT_CONSTANT(opline, opline->op2); - if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) { - zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - - - HANDLE_EXCEPTION(); - } - constant_name = Z_STR_P(constant_zv); - /* Magic 'class' for constant OP2 is caught at compile-time */ - if (IS_CONST != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); - - - ZEND_VM_NEXT_OPCODE(); - } - zv = IS_CONST == IS_CONST - ? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name) - : zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name); - - if (EXPECTED(zv != NULL)) { - c = Z_PTR_P(zv); - scope = EX(func)->op_array.scope; - if (!zend_verify_const_access(c, scope)) { - zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - - - HANDLE_EXCEPTION(); - } - - if (ce->ce_flags & ZEND_ACC_TRAIT) { - zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - - - HANDLE_EXCEPTION(); - } - - bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; - if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) { - if (c->ce->type == ZEND_USER_CLASS) { - /* Recursion protection only applied to user constants, GH-18463 */ - CONST_PROTECT_RECURSION(c); - } - zend_deprecated_class_constant(c, constant_name); - if (c->ce->type == ZEND_USER_CLASS) { - CONST_UNPROTECT_RECURSION(c); - } - - if (EG(exception)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - - - HANDLE_EXCEPTION(); - } - } - - value = &c->value; - // Enums require loading of all class constants to build the backed enum table - if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { - if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - - - HANDLE_EXCEPTION(); - } - } - if (Z_TYPE_P(value) == IS_CONSTANT_AST) { - if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - - - HANDLE_EXCEPTION(); - } - } - if (IS_CONST == IS_CONST && !is_constant_deprecated) { - CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); - } - } else { - zend_throw_error(NULL, "Undefined constant %s::%s", - ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - - - HANDLE_EXCEPTION(); - } - } while (0); - - ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); - - - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *array; uint32_t size; @@ -36272,7 +36607,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SP } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -36281,7 +36616,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPE SAVE_OPLINE(); container = &EX(This); - offset = RT_CONSTANT(opline, opline->op2); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { @@ -36298,7 +36633,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPE break; } } - if (IS_CONST == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(offset); } else { name = zval_try_get_tmp_string(offset, &tmp_name); @@ -36306,19 +36641,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPE break; } } - Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - if (IS_CONST != IS_CONST) { + Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } } while (0); - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -36328,7 +36663,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY SAVE_OPLINE(); container = &EX(This); - offset = RT_CONSTANT(opline, opline->op2); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if (IS_UNUSED == IS_CONST || (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -36344,7 +36679,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY } } - if (IS_CONST == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(offset); } else { name = zval_try_get_tmp_string(offset, &tmp_name); @@ -36356,21 +36691,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY result = (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - if (IS_CONST != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } isset_object_finish: - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -36457,13 +36791,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_UN } /* Set the new yielded key */ - if (IS_CONST != IS_UNUSED) { - zval *key = RT_CONSTANT(opline, opline->op2); - if ((IS_CONST & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + if (IS_TMP_VAR != IS_UNUSED) { + zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { key = Z_REFVAL_P(key); } ZVAL_COPY(&generator->key, key); - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (Z_TYPE(generator->key) == IS_LONG && Z_LVAL(generator->key) > generator->largest_used_integer_key @@ -36492,2067 +36826,2040 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_UN ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zend_class_entry *ce, *scope; - zend_class_constant *c; - zval *value, *zv, *constant_zv; - zend_string *constant_name; + zval *class_name; USE_OPLINE SAVE_OPLINE(); + if (IS_UNUSED == IS_UNUSED) { + Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else if (IS_UNUSED == IS_CONST) { + zend_class_entry *ce = CACHED_PTR(opline->extended_value); - do { - if (IS_UNUSED == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) { - value = CACHED_PTR(opline->extended_value + sizeof(void*)); - break; - } + if (UNEXPECTED(ce == NULL)) { + class_name = NULL; + ce = zend_fetch_class_by_name(Z_STR_P(class_name), Z_STR_P(class_name + 1), opline->op1.num); + CACHE_PTR(opline->extended_value, ce); } - if (IS_UNUSED == IS_CONST) { - if (EXPECTED(CACHED_PTR(opline->extended_value))) { - ce = CACHED_PTR(opline->extended_value); - } else { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } - CACHE_PTR(opline->extended_value, ce); - } - } else if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } + Z_CE_P(EX_VAR(opline->result.var)) = ce; + } else { + class_name = NULL; +try_class_name: + if (Z_TYPE_P(class_name) == IS_OBJECT) { + Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name); + } else if (Z_TYPE_P(class_name) == IS_STRING) { + Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num); + } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) { + class_name = Z_REFVAL_P(class_name); + goto try_class_name; } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - if (IS_UNUSED != IS_CONST - && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST - && EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { - value = CACHED_PTR(opline->extended_value + sizeof(void*)); - break; - } - - constant_zv = _get_zval_ptr_tmpvarcv(opline->op2_type, opline->op2, BP_VAR_R EXECUTE_DATA_CC); - if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) { - zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } - constant_name = Z_STR_P(constant_zv); - /* Magic 'class' for constant OP2 is caught at compile-time */ - if ((IS_TMP_VAR|IS_VAR|IS_CV) != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); - FREE_OP(opline->op2_type, opline->op2.var); - ZEND_VM_NEXT_OPCODE(); - } - zv = (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST - ? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name) - : zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name); - - if (EXPECTED(zv != NULL)) { - c = Z_PTR_P(zv); - scope = EX(func)->op_array.scope; - if (!zend_verify_const_access(c, scope)) { - zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } - - if (ce->ce_flags & ZEND_ACC_TRAIT) { - zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } - - bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; - if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) { - if (c->ce->type == ZEND_USER_CLASS) { - /* Recursion protection only applied to user constants, GH-18463 */ - CONST_PROTECT_RECURSION(c); - } - zend_deprecated_class_constant(c, constant_name); - if (c->ce->type == ZEND_USER_CLASS) { - CONST_UNPROTECT_RECURSION(c); - } - - if (EG(exception)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } - } - - value = &c->value; - // Enums require loading of all class constants to build the backed enum table - if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { - if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } - } - if (Z_TYPE_P(value) == IS_CONSTANT_AST) { - if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } } - if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && !is_constant_deprecated) { - CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); - } - } else { - zend_throw_error(NULL, "Undefined constant %s::%s", - ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); + zend_throw_error(NULL, "Class name must be a valid object or a string"); } - } while (0); + } - ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); - FREE_OP(opline->op2_type, opline->op2.var); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object; - zval *property; - zval *value; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; + zval *function_name; + zend_class_entry *ce; + uint32_t call_info; + zend_function *fbc; + zend_execute_data *call; SAVE_OPLINE(); - object = &EX(This); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - do { - value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); + if (IS_UNUSED == IS_CONST) { + /* no function found. try a static method in class */ + ce = CACHED_PTR(opline->result.num); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_op_object; + + HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (IS_UNUSED != IS_CONST) { + CACHE_PTR(opline->result.num, ce); } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { -assign_op_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - UNDEF_RESULT(); - break; - } + + HANDLE_EXCEPTION(); } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - zend_reference *ref; + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + if (IS_UNUSED == IS_CONST && + IS_UNUSED == IS_CONST && + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { + /* nothing to do */ + } else if (IS_UNUSED != IS_CONST && + IS_UNUSED == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else if (IS_UNUSED != IS_UNUSED) { + function_name = NULL; + if (IS_UNUSED != IS_CONST) { + if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - zptr = Z_REFVAL_P(zptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + if (IS_UNUSED & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } + } else if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } + zend_throw_error(NULL, "Method name must be a string"); - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - if (prop_info) { - /* special case for typed properties */ - zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_binary_op(zptr, zptr, value OPLINE_CC); - } - } while (0); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), zptr); - } + HANDLE_EXCEPTION(); + } while (0); } - } else { - zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - } while (0); - - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (ce->get_static_method) { + fbc = ce->get_static_method(ce, Z_STR_P(function_name)); + } else { + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + } + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(ce, Z_STR_P(function_name)); + } - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} -/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; + HANDLE_EXCEPTION(); + } + if (IS_UNUSED == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + if (IS_UNUSED != IS_CONST) { - SAVE_OPLINE(); - object = &EX(This); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - do { - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto pre_incdec_object; - } - if (IS_UNUSED == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; } + } else { + if (UNEXPECTED(ce->constructor == NULL)) { + zend_throw_error(NULL, "Cannot call constructor"); + HANDLE_EXCEPTION(); + } + if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { + zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); + HANDLE_EXCEPTION(); + } + fbc = ce->constructor; + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + } -pre_incdec_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(property); + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - UNDEF_RESULT(); - break; - } + zend_non_static_method_call(fbc); + HANDLE_EXCEPTION(); } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } + } else { + /* previous opcode is ZEND_FETCH_CLASS */ + if (IS_UNUSED == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { + if (Z_TYPE(EX(This)) == IS_OBJECT) { + ce = Z_OBJCE(EX(This)); } else { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); + ce = Z_CE(EX(This)); } - } else { - zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); } - } while (0); - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + call_info = ZEND_CALL_NESTED_FUNCTION; + } + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); + call->prev_execute_data = EX(call); + EX(call) = call; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; - - SAVE_OPLINE(); - object = &EX(This); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_UNUSED == IS_UNUSED) { + SAVE_OPLINE(); + zend_verify_missing_return_type(EX(func)); + HANDLE_EXCEPTION(); + } else { +/* prevents "undefined variable opline" errors */ +#if 0 || (IS_UNUSED != IS_UNUSED) + USE_OPLINE + zval *retval_ref, *retval_ptr; + zend_arg_info *ret_info = EX(func)->common.arg_info - 1; + retval_ref = retval_ptr = NULL; - do { - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto post_incdec_object; - } - if (IS_UNUSED == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (IS_UNUSED == IS_CONST) { + ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr); + retval_ref = retval_ptr = EX_VAR(opline->result.var); + } else if (IS_UNUSED == IS_VAR) { + if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) { + retval_ref = retval_ptr = Z_INDIRECT_P(retval_ptr); } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; + ZVAL_DEREF(retval_ptr); + } else if (IS_UNUSED == IS_CV) { + ZVAL_DEREF(retval_ptr); } -post_incdec_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + ZEND_VM_NEXT_OPCODE(); + } + + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { + SAVE_OPLINE(); + retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { + ZEND_VM_NEXT_OPCODE(); } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - ZVAL_NULL(EX_VAR(opline->result.var)); + + zend_reference *ref = NULL; + if (UNEXPECTED(retval_ref != retval_ptr)) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + ref = Z_REF_P(retval_ref); } else { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); + /* A cast might happen - unwrap the reference if this is a by-value return */ + if (Z_REFCOUNT_P(retval_ref) == 1) { + ZVAL_UNREF(retval_ref); + } else { + Z_DELREF_P(retval_ref); + ZVAL_COPY(retval_ref, retval_ptr); + } + retval_ptr = retval_ref; } - } else { - zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); } - } while (0); - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + SAVE_OPLINE(); + if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, 1, 0))) { + zend_verify_return_error(EX(func), retval_ptr); + HANDLE_EXCEPTION(); + } + ZEND_VM_NEXT_OPCODE(); +#endif + } +} - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + SAVE_OPLINE(); + zend_verify_never_error(EX(func)); + HANDLE_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - void **cache_slot = NULL; - - SAVE_OPLINE(); - container = &EX(This); + uint32_t arg_num; - if (IS_UNUSED == IS_CONST || - (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - break; - } - } - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_wrong_property_read(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_r_finish; - } while (0); + if (IS_UNUSED == IS_CONST) { + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + arg_num = zend_get_arg_offset_by_name( + EX(call)->func, arg_name, CACHE_ADDR(opline->result.num)) + 1; + if (UNEXPECTED(arg_num == 0)) { + /* Treat this as a by-value argument, and throw an error during SEND. */ + ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); + ZEND_VM_NEXT_OPCODE(); + } + } else { + arg_num = opline->op2.num; } - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); - - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_r_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { -fetch_obj_r_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - prop_offset = prop_info->offset; - goto fetch_obj_r_simple; - } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { - zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; - ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); - ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); - - uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (IS_UNUSED & IS_CV) { - GC_ADDREF(zobj); - } - if (IS_UNUSED & (IS_CV|IS_VAR|IS_TMP_VAR)) { - call_info |= ZEND_CALL_RELEASE_THIS; - } - zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); - call->prev_execute_data = execute_data; - call->call = NULL; - call->return_value = EX_VAR(opline->result.var); - call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); + if (EXPECTED(0)) { + if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); + } else { + ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); + } + } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); + } else { + ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); + } + ZEND_VM_NEXT_OPCODE(); +} - execute_data = call; - EG(current_execute_data) = execute_data; - zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + uint32_t arg_num; -#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) - opline = hook->op_array.opcodes; -#else - EX(opline) = hook->op_array.opcodes; -#endif - LOAD_OPLINE_EX(); + if (IS_UNUSED == IS_CONST) { + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + arg_num = zend_get_arg_offset_by_name( + EX(call)->func, arg_name, CACHE_ADDR(opline->result.num)) + 1; + if (UNEXPECTED(arg_num == 0)) { + /* Treat this as a by-value argument, and throw an error during SEND. */ + ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); + ZEND_VM_NEXT_OPCODE(); + } + } else { + arg_num = opline->op2.num; + } + if (EXPECTED(1)) { + if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); + } else { + ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); + } + } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); + } else { + ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); + } + ZEND_VM_NEXT_OPCODE(); +} +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_execute_data *call = execute_data->call; + if (EXPECTED(!(ZEND_CALL_INFO(call) & ZEND_CALL_MAY_HAVE_UNDEF))) { + ZEND_VM_NEXT_OPCODE(); + } - ZEND_VM_ENTER_EX(); - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + SAVE_OPLINE(); + zend_handle_undef_args(call); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NEW_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *result; + zend_function *constructor; + zend_class_entry *ce; + zend_execute_data *call; - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; - } - } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; - } - } - } - } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { + SAVE_OPLINE(); + if (IS_UNUSED == IS_CONST) { + ce = CACHED_PTR(opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; + HANDLE_EXCEPTION(); } + CACHE_PTR(opline->op2.num, ce); } - -#if ZEND_DEBUG - /* For non-standard object handlers, verify a declared property type in debug builds. - * Fetch prop_info before calling read_property(), as it may deallocate the object. */ - zend_property_info *prop_info = NULL; - if (zobj->handlers->read_property != zend_std_read_property) { - prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); - } -#endif - retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); -#if ZEND_DEBUG - if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { - ZVAL_OPT_DEREF(retval); - zend_verify_property_type(prop_info, retval, /* strict */ true); + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } -#endif + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + result = EX_VAR(opline->result.var); + if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { + ZVAL_UNDEF(result); + HANDLE_EXCEPTION(); + } - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_r_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); + constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); + if (constructor == NULL) { + /* If there are no arguments, skip over the DO_FCALL opcode. We check if the next + * opcode is DO_FCALL in case EXT instructions are used. */ + if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) { + ZEND_VM_NEXT_OPCODE_EX(1, 2); } - } while (0); -fetch_obj_r_finish: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + /* Perform a dummy function call */ + call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, + opline->extended_value, NULL); + } else { + if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { + init_func_run_time_cache(&constructor->op_array); + } + /* We are not handling overloaded classes right now */ + call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS, + constructor, + opline->extended_value, + Z_OBJ_P(result)); + Z_ADDREF_P(result); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + call->prev_execute_data = EX(call); + EX(call) = call; + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zval *array; + uint32_t size; USE_OPLINE - zval *property, *container, *result; SAVE_OPLINE(); - - container = &EX(This); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address( - result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), - (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (IS_UNUSED == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + array = EX_VAR(opline->result.var); + if (IS_UNUSED != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + } + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_ARR(array, zend_new_array(0)); + ZEND_VM_NEXT_OPCODE(); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *property, *container, *result; + + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); SAVE_OPLINE(); - container = &EX(This); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (IS_UNUSED == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - void **cache_slot = NULL; + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); - SAVE_OPLINE(); - container = &EX(This); + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); - if (IS_UNUSED == IS_CONST || - (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - break; - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - } - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_is_finish; - } while (0); - } - - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; + /* Set the new yielded value */ + if (IS_UNUSED != IS_UNUSED) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_UNUSED & (IS_CONST|IS_TMP_VAR)) { + zval *value; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value); + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + value = NULL; + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_UNUSED == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } + } else { + zval *value_ptr = NULL; - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_is_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { -fetch_obj_is_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + do { + if (IS_UNUSED == IS_VAR) { + ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION + && !Z_ISREF_P(value_ptr)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + ZVAL_COPY(&generator->value, value_ptr); + break; } } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - goto fetch_obj_is_simple; + if (Z_ISREF_P(value_ptr)) { + Z_ADDREF_P(value_ptr); + } else { + ZVAL_MAKE_REF_EX(value_ptr, 2); } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); + } while (0); - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } - } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; + zval *value = NULL; + + /* Consts, temporary variables and references need copying */ + if (IS_UNUSED == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } else if (IS_UNUSED == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + + + } else { + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_UNUSED == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } } } + } else { + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); + } - retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); + /* Set the new yielded key */ + if (IS_UNUSED != IS_UNUSED) { + zval *key = NULL; + if ((IS_UNUSED & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + key = Z_REFVAL_P(key); } + ZVAL_COPY(&generator->key, key); - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_is_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); + + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); } - } while (0); + } else { + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); + } -fetch_obj_is_finish: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; + } + + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); + ZEND_VM_RETURN(); +} - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) { + zval *result = EX_VAR(opline->result.var); + + ZVAL_OBJ(result, Z_OBJ(EX(This))); + Z_ADDREF_P(result); + ZEND_VM_NEXT_OPCODE(); + } else { + ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if 0 USE_OPLINE -#endif - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - /* Behave like FETCH_OBJ_W */ - if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + /* For symbol tables we need to deal with exactly the same problems as for property tables. */ + ZVAL_ARR(EX_VAR(opline->result.var), + zend_proptable_to_symtable(&EG(symbol_table), /* always_duplicate */ 1)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + ZVAL_BOOL(EX_VAR(opline->result.var), + (opline->extended_value & ZEND_ISEMPTY) ^ + (Z_TYPE(EX(This)) == IS_OBJECT)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (IS_UNUSED == IS_UNUSED) { + SAVE_OPLINE(); + if (UNEXPECTED(!EX(func)->common.scope)) { + zend_throw_error(NULL, "get_class() without arguments must be called from within a class"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } else { + zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated"); + ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + ZEND_VM_NEXT_OPCODE(); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + zval *op1; + + SAVE_OPLINE(); + op1 = NULL; + while (1) { + if (Z_TYPE_P(op1) == IS_OBJECT) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); + } else if ((IS_UNUSED & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + continue; + } else { + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_type_error("get_class(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(op1)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + break; + } + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container, *property, *result; - SAVE_OPLINE(); - container = &EX(This); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (IS_UNUSED == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + if (Z_TYPE(EX(This)) == IS_OBJECT) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE(EX(This))->name); + } else if (Z_CE(EX(This))) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_CE(EX(This))->name); + } else { + ZEND_ASSERT(!EX(func)->common.scope); + SAVE_OPLINE(); + zend_throw_error(NULL, "get_called_class() must be called from within a class"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - SAVE_OPLINE(); - object = &EX(This); - value = RT_CONSTANT((opline+1), (opline+1)->op1); + ZVAL_LONG(EX_VAR(opline->result.var), EX_NUM_ARGS()); + ZEND_VM_NEXT_OPCODE(); +} - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_array *ht; + uint32_t arg_count, result_size, skip; + + arg_count = EX_NUM_ARGS(); + if (IS_UNUSED == IS_CONST) { + skip = Z_LVAL_P(RT_CONSTANT(opline, opline->op1)); + if (arg_count < skip) { + result_size = 0; + } else { + result_size = arg_count - skip; } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; + } else { + skip = 0; + result_size = arg_count; } -assign_object: - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + if (result_size) { + SAVE_OPLINE(); + uint32_t first_extra_arg = EX(func)->op_array.num_args; -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); + ht = zend_new_array(result_size); + ZVAL_ARR(EX_VAR(opline->result.var), ht); + zend_hash_real_init_packed(ht); + ZEND_HASH_FILL_PACKED(ht) { + zval *p, *q; + uint32_t i = skip; + p = EX_VAR_NUM(i); + if (arg_count > first_extra_arg) { + while (i < first_extra_arg) { + q = p; + if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) { + ZVAL_DEREF(q); + if (Z_OPT_REFCOUNTED_P(q)) { + Z_ADDREF_P(q); } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; + ZEND_HASH_FILL_SET(q); + } else { + ZEND_HASH_FILL_SET_NULL(); } + ZEND_HASH_FILL_NEXT(); + p++; + i++; } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CONST != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CONST == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_CONST == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; + if (skip < first_extra_arg) { + skip = 0; + } else { + skip -= first_extra_arg; } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; + p = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T + skip); + } + while (i < arg_count) { + q = p; + if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) { + ZVAL_DEREF(q); + if (Z_OPT_REFCOUNTED_P(q)) { + Z_ADDREF_P(q); } - goto assign_obj_simple; + ZEND_HASH_FILL_SET(q); + } else { + ZEND_HASH_FILL_SET_NULL(); } - /* Fall through to write_property for hooks. */ + ZEND_HASH_FILL_NEXT(); + p++; + i++; } - } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + } ZEND_HASH_FILL_END(); + ht->nNumOfElements = result_size; } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { + ZVAL_EMPTY_ARRAY(EX_VAR(opline->result.var)); + } + ZEND_VM_NEXT_OPCODE(); +} +/* Contrary to what its name indicates, ZEND_COPY_TMP may receive and define references. */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_execute_data *call = EX(call); - UNDEF_RESULT(); - goto exit_assign_obj; + if (opline->extended_value != (uint32_t)-1) { + zend_object *closure = CACHED_PTR(opline->extended_value); + if (closure) { + ZVAL_OBJ_COPY(EX_VAR(opline->result.var), closure); + } else { + /* Rotate the key for better hash distribution. */ + const int shift = sizeof(size_t) == 4 ? 6 : 7; + zend_ulong key = (zend_ulong)(uintptr_t)call->func; + key = (key >> shift) | (key << ((sizeof(key) * 8) - shift)); + zval *closure_zv = zend_hash_index_lookup(&EG(callable_convert_cache), key); + if (Z_TYPE_P(closure_zv) == IS_NULL) { + zend_closure_from_frame(closure_zv, call); + } + ZEND_ASSERT(Z_TYPE_P(closure_zv) == IS_OBJECT); + closure = Z_OBJ_P(closure_zv); + ZVAL_OBJ_COPY(EX_VAR(opline->result.var), closure); + CACHE_PTR(opline->extended_value, closure); } + } else { + zend_closure_from_frame(EX_VAR(opline->result.var), call); } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_DEREF(value); + if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) { + OBJ_RELEASE(Z_OBJ(call->This)); } - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + EX(call) = call->prev_execute_data; -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } + zend_vm_stack_free_call_frame(call); + ZEND_VM_NEXT_OPCODE(); +} -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FRAMELESS_ICALL_0_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + SAVE_OPLINE(); + zval *result = EX_VAR(opline->result.var); + ZVAL_NULL(result); - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); +#if 0 || 0 + if (0 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) { + zend_frameless_observed_call(execute_data); + } else +#endif + { + zend_frameless_function_0 function = (zend_frameless_function_0)ZEND_FLF_HANDLER(opline); + function(result); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FRAMELESS_ICALL_0_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - SAVE_OPLINE(); - object = &EX(This); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } + zval *result = EX_VAR(opline->result.var); + ZVAL_NULL(result); -assign_object: - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_TMP_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_TMP_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_TMP_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); +#if 0 || 1 + if (1 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) { + zend_frameless_observed_call(execute_data); + } else +#endif + { + zend_frameless_function_0 function = (zend_frameless_function_0)ZEND_FLF_HANDLER(opline); + function(result); } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; + zval *object; + zval *property; + zval *value; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; zend_object *zobj; zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; SAVE_OPLINE(); object = &EX(This); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); -assign_object: - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; + do { + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_op_object; + } + if (IS_UNUSED == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } +assign_op_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + UNDEF_RESULT(); + break; + } + } + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); } + } else { + zend_reference *ref; - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + zptr = Z_REFVAL_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; } } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; + + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + if (prop_info) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_binary_op(zptr, zptr, value OPLINE_CC); } - goto assign_obj_simple; + } while (0); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), zptr); } - /* Fall through to write_property for hooks. */ } + } else { + zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } - } - - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } + } while (0); - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; zend_object *zobj; zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; SAVE_OPLINE(); object = &EX(This); - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; + do { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto pre_incdec_object; + } + if (IS_UNUSED == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CV != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CV == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_CV == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; +pre_incdec_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + UNDEF_RESULT(); + break; + } + } + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); + zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } + } else { + zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - - - UNDEF_RESULT(); - goto exit_assign_obj; + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } - } - - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } + } while (0); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *property, *container, *value_ptr; + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; SAVE_OPLINE(); + object = &EX(This); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - container = &EX(This); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (1) { - if (IS_UNUSED == IS_UNUSED) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + do { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto post_incdec_object; + } + if (IS_UNUSED == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; } - } else { - zend_assign_to_property_reference(container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC); - } + +post_incdec_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; + } + } + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); + } + } else { + zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); + } + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - ZEND_VM_NEXT_OPCODE_EX(1, 2); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *property, *container, *value_ptr; + zval *container; + void **cache_slot = NULL; SAVE_OPLINE(); - container = &EX(This); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_UNUSED & (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 (1) { - if (IS_UNUSED == IS_UNUSED) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + if (IS_UNUSED == IS_CONST || + (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if ((IS_UNUSED & IS_CV) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } } - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } - } - } else { - zend_assign_to_property_reference(container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC); + zend_wrong_property_read(container, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; + } while (0); } + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_CV == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_r_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { +fetch_obj_r_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + prop_offset = prop_info->offset; + goto fetch_obj_r_simple; + } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { + zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; + ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); + ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_string **rope; - zval *var; + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (IS_UNUSED & IS_CV) { + GC_ADDREF(zobj); + } + if (IS_UNUSED & (IS_CV|IS_VAR|IS_TMP_VAR)) { + call_info |= ZEND_CALL_RELEASE_THIS; + } + zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); + call->prev_execute_data = execute_data; + call->call = NULL; + call->return_value = EX_VAR(opline->result.var); + call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); - /* Compiler allocates the necessary number of zval slots to keep the rope */ - rope = (zend_string**)EX_VAR(opline->result.var); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - rope[0] = Z_STR_P(var); - if (UNEXPECTED(Z_REFCOUNTED_P(var))) { - Z_ADDREF_P(var); - } - } else { - var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - rope[0] = zend_string_copy(Z_STR_P(var)); - } else { - rope[0] = Z_STR_P(var); + execute_data = call; + EG(current_execute_data) = execute_data; + zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); + +#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) + opline = hook->op_array.opcodes; +#else + EX(opline) = hook->op_array.opcodes; +#endif + LOAD_OPLINE_EX(); + + + + + ZEND_VM_ENTER_EX(); + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } + } } + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); } else { - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); + name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; } - rope[0] = zval_get_string_func(var); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - } - ZEND_VM_NEXT_OPCODE(); + +#if ZEND_DEBUG + /* For non-standard object handlers, verify a declared property type in debug builds. + * Fetch prop_info before calling read_property(), as it may deallocate the object. */ + zend_property_info *prop_info = NULL; + if (zobj->handlers->read_property != zend_std_read_property) { + prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); + } +#endif + retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO + && ZEND_TYPE_IS_SET(prop_info->type)) { + ZVAL_OPT_DEREF(retval); + zend_verify_property_type(prop_info, retval, /* strict */ true); + } +#endif + + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_r_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } + } while (0); + +fetch_obj_r_finish: + + + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zval *class_name; USE_OPLINE + zval *property, *container, *result; SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_class_entry *ce = CACHED_PTR(opline->extended_value); - if (UNEXPECTED(ce == NULL)) { - class_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - ce = zend_fetch_class_by_name(Z_STR_P(class_name), Z_STR_P(class_name + 1), opline->op1.num); - CACHE_PTR(opline->extended_value, ce); - } - Z_CE_P(EX_VAR(opline->result.var)) = ce; - } else { - class_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); -try_class_name: - if (Z_TYPE_P(class_name) == IS_OBJECT) { - Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name); - } else if (Z_TYPE_P(class_name) == IS_STRING) { - Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) { - class_name = Z_REFVAL_P(class_name); - goto try_class_name; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Class name must be a valid object or a string"); - } - } + container = &EX(This); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + zend_fetch_property_address( + result, container, IS_UNUSED, property, IS_CV, + ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + if (IS_UNUSED == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zval *object; - zend_function *fbc; - zend_class_entry *called_scope; - zend_object *obj; - zend_execute_data *call; - uint32_t call_info; + zval *property, *container, *result; SAVE_OPLINE(); + container = &EX(This); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - object = &EX(This); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_UNUSED == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + void **cache_slot = NULL; + + SAVE_OPLINE(); + container = &EX(This); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ + + if (IS_UNUSED == IS_CONST || + (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } + if (IS_CV == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { + } + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; + } while (0); + } + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Method name must be a string"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_CV == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - HANDLE_EXCEPTION(); - } while (0); - } + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_is_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { +fetch_obj_is_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + goto fetch_obj_is_simple; + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); - if (IS_UNUSED == IS_UNUSED) { - obj = Z_OBJ_P(object); - } else { - do { - if (IS_UNUSED != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - } else { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - zend_reference *ref = Z_REF_P(object); + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); - object = &ref->val; - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - if (IS_UNUSED & IS_VAR) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_ADDREF_P(object); + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } } } - break; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); } - } - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - object = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; } - HANDLE_EXCEPTION(); } } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - } - zend_invalid_method_call(object, function_name); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - HANDLE_EXCEPTION(); } - } while (0); - } - - called_scope = obj->ce; + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + } else { + name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; + } + } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else { - zend_object *orig_obj = obj; + retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } - /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); - } - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); - } - if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ - if (GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); - } - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_is_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); } - } + } while (0); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } +fetch_obj_is_finish: - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { - zend_objects_store_del(obj); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - /* call static method */ - obj = (zend_object*)called_scope; - call_info = ZEND_CALL_NESTED_FUNCTION; - } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { - if (IS_UNUSED == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ - } - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; - } - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, obj); - call->prev_execute_data = EX(call); - EX(call) = call; - ZEND_VM_NEXT_OPCODE(); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { +#if 0 USE_OPLINE - zval *function_name; - zend_class_entry *ce; - uint32_t call_info; - zend_function *fbc; - zend_execute_data *call; - - SAVE_OPLINE(); +#endif - if (IS_UNUSED == IS_CONST) { - /* no function found. try a static method in class */ - ce = CACHED_PTR(opline->result.num); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - CACHE_PTR(opline->result.num, ce); - } - } - } else if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - - if (IS_UNUSED == IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { - /* nothing to do */ - } else if (IS_UNUSED != IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Method name must be a string"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } while (0); - } - } - - if (ce->get_static_method) { - fbc = ce->get_static_method(ce, Z_STR_P(function_name)); - } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - } - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(ce, Z_STR_P(function_name)); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { - CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } - } else { - if (UNEXPECTED(ce->constructor == NULL)) { - zend_throw_error(NULL, "Cannot call constructor"); - HANDLE_EXCEPTION(); - } - if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { - zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); - HANDLE_EXCEPTION(); - } - fbc = ce->constructor; - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - } - - if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { - if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - ce = (zend_class_entry*)Z_OBJ(EX(This)); - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - } else { - zend_non_static_method_call(fbc); - HANDLE_EXCEPTION(); + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + /* Behave like FETCH_OBJ_W */ + if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - /* previous opcode is ZEND_FETCH_CLASS */ - if (IS_UNUSED == IS_UNUSED - && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { - if (Z_TYPE(EX(This)) == IS_OBJECT) { - ce = Z_OBJCE(EX(This)); - } else { - ce = Z_CE(EX(This)); + if (IS_UNUSED == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } } } - call_info = ZEND_CALL_NESTED_FUNCTION; + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, ce); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zval *array; - uint32_t size; USE_OPLINE + zval *container, *property, *result; SAVE_OPLINE(); - array = EX_VAR(opline->result.var); - if (IS_UNUSED != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); - } - ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZVAL_ARR(array, zend_new_array(0)); - ZEND_VM_NEXT_OPCODE(); + container = &EX(This); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + + + if (IS_UNUSED == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - zval *offset; + zval *object, *value, tmp; + zend_object *zobj; zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - container = &EX(This); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + object = &EX(This); + value = RT_CONSTANT((opline+1), (opline+1)->op1); - do { - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - if (Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (Z_TYPE_P(container) != IS_OBJECT) { - if (IS_UNUSED == IS_CV - && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; + } + zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; } - break; + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CONST != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CONST == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CONST == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; } } else { - break; - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(offset); - } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - break; + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ } } - Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - } while (0); - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + } else { + name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + UNDEF_RESULT(); + goto exit_assign_obj; + } + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - int result; - zval *offset; - zend_string *name, *tmp_name; + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_DEREF(value); + } - SAVE_OPLINE(); - container = &EX(This); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if (IS_UNUSED == IS_CONST || - (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } - } else { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(offset); - } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - result = 0; - goto isset_object_finish; - } +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); } - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); } -isset_object_finish: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); + + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); + object = &EX(This); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; + } + zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } - /* Set the new yielded value */ - if (IS_UNUSED != IS_UNUSED) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_UNUSED & (IS_CONST|IS_TMP_VAR)) { - zval *value; +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - value = NULL; - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_UNUSED == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; } } - } else { - zval *value_ptr = NULL; - - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - do { - if (IS_UNUSED == IS_VAR) { - ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION - && !Z_ISREF_P(value_ptr)) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - ZVAL_COPY(&generator->value, value_ptr); - break; + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); } + zobj->properties = zend_array_dup(zobj->properties); } - if (Z_ISREF_P(value_ptr)) { - Z_ADDREF_P(value_ptr); - } else { - ZVAL_MAKE_REF_EX(value_ptr, 2); + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; } - ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); - } while (0); - - - } - } else { - zval *value = NULL; - - /* Consts, temporary variables and references need copying */ - if (IS_UNUSED == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); } - } else if (IS_UNUSED == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_TMP_VAR == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_TMP_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_UNUSED == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; } + /* Fall through to write_property for hooks. */ } } + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); + name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + goto exit_assign_obj; + } } - /* Set the new yielded key */ - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *key = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { - key = Z_REFVAL_P(key); - } - ZVAL_COPY(&generator->key, key); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_DEREF(value); + } - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); - } - } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + + + + + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; + + SAVE_OPLINE(); + object = &EX(This); + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; + } + zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CV != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CV == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CV == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ + } + } + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); } else { - generator->send_target = NULL; + name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { + + + UNDEF_RESULT(); + goto exit_assign_obj; + } } - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_DEREF(value); + } + + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } + + +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + + + + + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *property, *container, *value_ptr; + SAVE_OPLINE(); - ZEND_VM_RETURN(); + container = &EX(This); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + + value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + + if (1) { + if (IS_UNUSED == IS_UNUSED) { + if (IS_CV == IS_CONST) { + zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } + } else { + if (IS_CV == IS_CONST) { + zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } + } + } else { + zend_assign_to_property_reference(container, IS_UNUSED, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } + + + + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *property, *container, *value_ptr; + + SAVE_OPLINE(); + + container = &EX(This); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + + value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); + + if (1) { + if (IS_UNUSED == IS_UNUSED) { + if (IS_CV == IS_CONST) { + zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } + } else { + if (IS_CV == IS_CONST) { + zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } + } + } else { + zend_assign_to_property_reference(container, IS_UNUSED, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } + + + + + + + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_INIT_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_string **rope; + zval *var; + + /* Compiler allocates the necessary number of zval slots to keep the rope */ + rope = (zend_string**)EX_VAR(opline->result.var); + if (IS_CV == IS_CONST) { + var = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + rope[0] = Z_STR_P(var); + if (UNEXPECTED(Z_REFCOUNTED_P(var))) { + Z_ADDREF_P(var); + } + } else { + var = EX_VAR(opline->op2.var); + if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { + if (IS_CV == IS_CV) { + rope[0] = zend_string_copy(Z_STR_P(var)); + } else { + rope[0] = Z_STR_P(var); + } + } else { + SAVE_OPLINE(); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + } + rope[0] = zval_get_string_func(var); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *class_name; USE_OPLINE SAVE_OPLINE(); - if (IS_UNUSED == IS_UNUSED) { + if (IS_CV == IS_UNUSED) { Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else if (IS_UNUSED == IS_CONST) { + } else if (IS_CV == IS_CONST) { zend_class_entry *ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { - class_name = NULL; + class_name = EX_VAR(opline->op2.var); ce = zend_fetch_class_by_name(Z_STR_P(class_name), Z_STR_P(class_name + 1), opline->op1.num); CACHE_PTR(opline->extended_value, ce); } Z_CE_P(EX_VAR(opline->result.var)) = ce; } else { - class_name = NULL; + class_name = EX_VAR(opline->op2.var); try_class_name: if (Z_TYPE_P(class_name) == IS_OBJECT) { Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name); } else if (Z_TYPE_P(class_name) == IS_STRING) { Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num); - } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) { + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) { class_name = Z_REFVAL_P(class_name); goto try_class_name; } else { - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -38566,7 +38873,170 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_S ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + zval *object; + zend_function *fbc; + zend_class_entry *called_scope; + zend_object *obj; + zend_execute_data *call; + uint32_t call_info; + + SAVE_OPLINE(); + + object = &EX(This); + + if (IS_CV != IS_CONST) { + function_name = EX_VAR(opline->op2.var); + } + + if (IS_CV != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + + + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Method name must be a string"); + + + + + HANDLE_EXCEPTION(); + } while (0); + } + + if (IS_UNUSED == IS_UNUSED) { + obj = Z_OBJ_P(object); + } else { + do { + if (IS_UNUSED != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + } else { + if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + if (IS_UNUSED & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } + break; + } + } + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + object = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_CV != IS_CONST) { + + + } + HANDLE_EXCEPTION(); + } + } + if (IS_CV == IS_CONST) { + function_name = EX_VAR(opline->op2.var); + } + zend_invalid_method_call(object, function_name); + + + + + HANDLE_EXCEPTION(); + } + } while (0); + } + + called_scope = obj->ce; + + if (IS_CV == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else { + zend_object *orig_obj = obj; + + if (IS_CV == IS_CONST) { + function_name = EX_VAR(opline->op2.var); + } + + /* First, locate the function. */ + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); + } + + + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + HANDLE_EXCEPTION(); + } + if (IS_CV == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(obj == orig_obj)) { + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); + } + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + } + + if (IS_CV != IS_CONST) { + + + } + + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { + if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; + } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { + if (IS_UNUSED == IS_CV) { + GC_ADDREF(obj); /* For $this pointer */ + } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; + } + + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, obj); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; @@ -38587,7 +39057,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M HANDLE_EXCEPTION(); } - if (IS_UNUSED != IS_CONST) { + if (IS_CV != IS_CONST) { CACHE_PTR(opline->result.num, ce); } } @@ -38603,24 +39073,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M } if (IS_UNUSED == IS_CONST && - IS_UNUSED == IS_CONST && + IS_CV == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_UNUSED != IS_CONST && - IS_UNUSED == IS_CONST && + IS_CV == IS_CONST && EXPECTED(CACHED_PTR(opline->result.num) == ce)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else if (IS_UNUSED != IS_UNUSED) { - function_name = NULL; - if (IS_UNUSED != IS_CONST) { + } else if (IS_CV != IS_UNUSED) { + function_name = EX_VAR(opline->op2.var); + if (IS_CV != IS_CONST) { if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if (IS_UNUSED & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + if (IS_CV & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -38637,7 +39107,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { @@ -38647,7 +39117,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_CONST && + if (IS_CV == IS_CONST && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); @@ -38655,7 +39125,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } - if (IS_UNUSED != IS_CONST) { + if (IS_CV != IS_CONST) { } @@ -38704,250 +39174,127 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_M ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - if (IS_UNUSED == IS_UNUSED) { - SAVE_OPLINE(); - zend_verify_missing_return_type(EX(func)); - HANDLE_EXCEPTION(); - } else { -/* prevents "undefined variable opline" errors */ -#if 0 || (IS_UNUSED != IS_UNUSED) - USE_OPLINE - zval *retval_ref, *retval_ptr; - zend_arg_info *ret_info = EX(func)->common.arg_info - 1; - retval_ref = retval_ptr = NULL; + zval *array; + uint32_t size; + USE_OPLINE - if (IS_UNUSED == IS_CONST) { - ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr); - retval_ref = retval_ptr = EX_VAR(opline->result.var); - } else if (IS_UNUSED == IS_VAR) { - if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) { - retval_ref = retval_ptr = Z_INDIRECT_P(retval_ptr); - } - ZVAL_DEREF(retval_ptr); - } else if (IS_UNUSED == IS_CV) { - ZVAL_DEREF(retval_ptr); - } - - if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { - ZEND_VM_NEXT_OPCODE(); - } - - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { - SAVE_OPLINE(); - retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { - ZEND_VM_NEXT_OPCODE(); - } - } - - zend_reference *ref = NULL; - if (UNEXPECTED(retval_ref != retval_ptr)) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - ref = Z_REF_P(retval_ref); - } else { - /* A cast might happen - unwrap the reference if this is a by-value return */ - if (Z_REFCOUNT_P(retval_ref) == 1) { - ZVAL_UNREF(retval_ref); - } else { - Z_DELREF_P(retval_ref); - ZVAL_COPY(retval_ref, retval_ptr); - } - retval_ptr = retval_ref; - } - } - - SAVE_OPLINE(); - if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, 1, 0))) { - zend_verify_return_error(EX(func), retval_ptr); - HANDLE_EXCEPTION(); + SAVE_OPLINE(); + array = EX_VAR(opline->result.var); + if (IS_UNUSED != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); } + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_ARR(array, zend_new_array(0)); ZEND_VM_NEXT_OPCODE(); -#endif } } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - SAVE_OPLINE(); - zend_verify_never_error(EX(func)); - HANDLE_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - uint32_t arg_num; + zval *container; + zval *offset; + zend_string *name, *tmp_name; - if (IS_UNUSED == IS_CONST) { - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - arg_num = zend_get_arg_offset_by_name( - EX(call)->func, arg_name, CACHE_ADDR(opline->result.num)) + 1; - if (UNEXPECTED(arg_num == 0)) { - /* Treat this as a by-value argument, and throw an error during SEND. */ - ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); - ZEND_VM_NEXT_OPCODE(); - } - } else { - arg_num = opline->op2.num; - } + SAVE_OPLINE(); + container = &EX(This); + offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(0)) { - if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); + do { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + if (IS_UNUSED == IS_CV + && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + break; + } + } else { + break; + } + } + if (IS_CV == IS_CONST) { + name = Z_STR_P(offset); } else { - ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); + name = zval_try_get_tmp_string(offset, &tmp_name); + if (UNEXPECTED(!name)) { + break; + } } - } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); - } else { - ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - uint32_t arg_num; - - if (IS_UNUSED == IS_CONST) { - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - arg_num = zend_get_arg_offset_by_name( - EX(call)->func, arg_name, CACHE_ADDR(opline->result.num)) + 1; - if (UNEXPECTED(arg_num == 0)) { - /* Treat this as a by-value argument, and throw an error during SEND. */ - ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); - ZEND_VM_NEXT_OPCODE(); + Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } - } else { - arg_num = opline->op2.num; - } + } while (0); - if (EXPECTED(1)) { - if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); - } else { - ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); - } - } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); - } else { - ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF); - } - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_execute_data *call = execute_data->call; - if (EXPECTED(!(ZEND_CALL_INFO(call) & ZEND_CALL_MAY_HAVE_UNDEF))) { - ZEND_VM_NEXT_OPCODE(); - } - SAVE_OPLINE(); - zend_handle_undef_args(call); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NEW_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *result; - zend_function *constructor; - zend_class_entry *ce; - zend_execute_data *call; + zval *container; + int result; + zval *offset; + zend_string *name, *tmp_name; SAVE_OPLINE(); - if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); + container = &EX(This); + offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + + if (IS_UNUSED == IS_CONST || + (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } - CACHE_PTR(opline->op2.num, ce); - } - } else if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); + } else { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } - } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - - result = EX_VAR(opline->result.var); - if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { - ZVAL_UNDEF(result); - HANDLE_EXCEPTION(); } - constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); - if (constructor == NULL) { - /* If there are no arguments, skip over the DO_FCALL opcode. We check if the next - * opcode is DO_FCALL in case EXT instructions are used. */ - if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) { - ZEND_VM_NEXT_OPCODE_EX(1, 2); + if (IS_CV == IS_CONST) { + name = Z_STR_P(offset); + } else { + name = zval_try_get_tmp_string(offset, &tmp_name); + if (UNEXPECTED(!name)) { + result = 0; + goto isset_object_finish; } + } - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - /* Perform a dummy function call */ - call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, - opline->extended_value, NULL); - } else { - if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { - init_func_run_time_cache(&constructor->op_array); - } - /* We are not handling overloaded classes right now */ - call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS, - constructor, - opline->extended_value, - Z_OBJ_P(result)); - Z_ADDREF_P(result); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } - call->prev_execute_data = EX(call); - EX(call) = call; - ZEND_VM_NEXT_OPCODE(); -} +isset_object_finish: -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zval *array; - uint32_t size; - USE_OPLINE - SAVE_OPLINE(); - array = EX_VAR(opline->result.var); - if (IS_UNUSED != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); - } - ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZVAL_ARR(array, zend_new_array(0)); - ZEND_VM_NEXT_OPCODE(); - } + + + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -39034,9 +39381,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_UN } /* Set the new yielded key */ - if (IS_UNUSED != IS_UNUSED) { - zval *key = NULL; - if ((IS_UNUSED & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + if (IS_CV != IS_UNUSED) { + zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + if ((IS_CV & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { key = Z_REFVAL_P(key); } ZVAL_COPY(&generator->key, key); @@ -39069,4697 +39416,4291 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_UN ZEND_VM_RETURN(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_THIS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_NOT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *val; - if (EXPECTED(Z_TYPE(EX(This)) == IS_OBJECT)) { - zval *result = EX_VAR(opline->result.var); - - ZVAL_OBJ(result, Z_OBJ(EX(This))); - Z_ADDREF_P(result); - ZEND_VM_NEXT_OPCODE(); + val = EX_VAR(opline->op1.var); + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + /* The result and op1 can be the same cv zval */ + const uint32_t orig_val_type = Z_TYPE_INFO_P(val); + ZVAL_TRUE(EX_VAR(opline->result.var)); + if (IS_CV == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } } else { - ZEND_VM_TAIL_CALL(zend_this_not_in_object_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } -} + SAVE_OPLINE(); + ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val)); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - /* For symbol tables we need to deal with exactly the same problems as for property tables. */ - ZVAL_ARR(EX_VAR(opline->result.var), - zend_proptable_to_symtable(&EG(symbol_table), /* always_duplicate */ 1)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_THIS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_pre_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *var_ptr; - ZVAL_BOOL(EX_VAR(opline->result.var), - (opline->extended_value & ZEND_ISEMPTY) ^ - (Z_TYPE(EX(This)) == IS_OBJECT)); - ZEND_VM_NEXT_OPCODE(); -} + var_ptr = EX_VAR(opline->op1.var); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE + SAVE_OPLINE(); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(var_ptr); + } - if (IS_UNUSED == IS_UNUSED) { - SAVE_OPLINE(); - if (UNEXPECTED(!EX(func)->common.scope)) { - zend_throw_error(NULL, "get_class() without arguments must be called from within a class"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } else { - zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated"); - ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, NULL OPLINE_CC EXECUTE_DATA_CC); + break; } - ZEND_VM_NEXT_OPCODE(); } - } else { - zval *op1; + increment_function(var_ptr); + } while (0); - SAVE_OPLINE(); - op1 = NULL; - while (1) { - if (Z_TYPE_P(op1) == IS_OBJECT) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); - } else if ((IS_UNUSED & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - continue; - } else { - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_type_error("get_class(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(op1)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - } - break; - } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *var_ptr; - if (Z_TYPE(EX(This)) == IS_OBJECT) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE(EX(This))->name); - } else if (Z_CE(EX(This))) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_CE(EX(This))->name); - } else { - ZEND_ASSERT(!EX(func)->common.scope); - SAVE_OPLINE(); - zend_throw_error(NULL, "get_called_class() must be called from within a class"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); + var_ptr = EX_VAR(opline->op1.var); + + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_increment_function(var_ptr); + if (UNEXPECTED(0)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); } - ZEND_VM_NEXT_OPCODE(); + + ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *var_ptr; - ZVAL_LONG(EX_VAR(opline->result.var), EX_NUM_ARGS()); - ZEND_VM_NEXT_OPCODE(); + var_ptr = EX_VAR(opline->op1.var); + + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_increment_function(var_ptr); + if (UNEXPECTED(1)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); + } + + ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_pre_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_array *ht; - uint32_t arg_count, result_size, skip; + zval *var_ptr; - arg_count = EX_NUM_ARGS(); - if (IS_UNUSED == IS_CONST) { - skip = Z_LVAL_P(RT_CONSTANT(opline, opline->op1)); - if (arg_count < skip) { - result_size = 0; - } else { - result_size = arg_count - skip; - } - } else { - skip = 0; - result_size = arg_count; + var_ptr = EX_VAR(opline->op1.var); + + SAVE_OPLINE(); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(var_ptr); } - if (result_size) { - SAVE_OPLINE(); - uint32_t first_extra_arg = EX(func)->op_array.num_args; + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); - ht = zend_new_array(result_size); - ZVAL_ARR(EX_VAR(opline->result.var), ht); - zend_hash_real_init_packed(ht); - ZEND_HASH_FILL_PACKED(ht) { - zval *p, *q; - uint32_t i = skip; - p = EX_VAR_NUM(i); - if (arg_count > first_extra_arg) { - while (i < first_extra_arg) { - q = p; - if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) { - ZVAL_DEREF(q); - if (Z_OPT_REFCOUNTED_P(q)) { - Z_ADDREF_P(q); - } - ZEND_HASH_FILL_SET(q); - } else { - ZEND_HASH_FILL_SET_NULL(); - } - ZEND_HASH_FILL_NEXT(); - p++; - i++; - } - if (skip < first_extra_arg) { - skip = 0; - } else { - skip -= first_extra_arg; - } - p = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T + skip); - } - while (i < arg_count) { - q = p; - if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) { - ZVAL_DEREF(q); - if (Z_OPT_REFCOUNTED_P(q)) { - Z_ADDREF_P(q); - } - ZEND_HASH_FILL_SET(q); - } else { - ZEND_HASH_FILL_SET_NULL(); - } - ZEND_HASH_FILL_NEXT(); - p++; - i++; + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, NULL OPLINE_CC EXECUTE_DATA_CC); + break; } - } ZEND_HASH_FILL_END(); - ht->nNumOfElements = result_size; - } else { - ZVAL_EMPTY_ARRAY(EX_VAR(opline->result.var)); + } + decrement_function(var_ptr); + } while (0); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } - ZEND_VM_NEXT_OPCODE(); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* Contrary to what its name indicates, ZEND_COPY_TMP may receive and define references. */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_execute_data *call = EX(call); + zval *var_ptr; - if (opline->extended_value != (uint32_t)-1) { - zend_object *closure = CACHED_PTR(opline->extended_value); - if (closure) { - ZVAL_OBJ_COPY(EX_VAR(opline->result.var), closure); - } else { - /* Rotate the key for better hash distribution. */ - const int shift = sizeof(size_t) == 4 ? 6 : 7; - zend_ulong key = (zend_ulong)(uintptr_t)call->func; - key = (key >> shift) | (key << ((sizeof(key) * 8) - shift)); - zval *closure_zv = zend_hash_index_lookup(&EG(callable_convert_cache), key); - if (Z_TYPE_P(closure_zv) == IS_NULL) { - zend_closure_from_frame(closure_zv, call); - } - ZEND_ASSERT(Z_TYPE_P(closure_zv) == IS_OBJECT); - closure = Z_OBJ_P(closure_zv); - ZVAL_OBJ_COPY(EX_VAR(opline->result.var), closure); - CACHE_PTR(opline->extended_value, closure); + var_ptr = EX_VAR(opline->op1.var); + + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_decrement_function(var_ptr); + if (UNEXPECTED(0)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); } - } else { - zend_closure_from_frame(EX_VAR(opline->result.var), call); + ZEND_VM_NEXT_OPCODE(); } - if (ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS) { - OBJ_RELEASE(Z_OBJ(call->This)); - } + ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); +} - EX(call) = call->prev_execute_data; +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; - zend_vm_stack_free_call_frame(call); + var_ptr = EX_VAR(opline->op1.var); - ZEND_VM_NEXT_OPCODE(); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + fast_long_decrement_function(var_ptr); + if (UNEXPECTED(1)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + } + ZEND_VM_NEXT_OPCODE(); + } + + ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FRAMELESS_ICALL_0_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_post_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - SAVE_OPLINE(); + zval *var_ptr; - zval *result = EX_VAR(opline->result.var); - ZVAL_NULL(result); + var_ptr = EX_VAR(opline->op1.var); -#if 0 || 0 - if (0 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) { - zend_frameless_observed_call(execute_data); - } else -#endif - { - zend_frameless_function_0 function = (zend_frameless_function_0)ZEND_FLF_HANDLER(opline); - function(result); + SAVE_OPLINE(); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(var_ptr); } + + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, EX_VAR(opline->result.var) OPLINE_CC EXECUTE_DATA_CC); + break; + } + } + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + + increment_function(var_ptr); + } while (0); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FRAMELESS_ICALL_0_SPEC_OBSERVER_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - SAVE_OPLINE(); + zval *var_ptr; - zval *result = EX_VAR(opline->result.var); - ZVAL_NULL(result); + var_ptr = EX_VAR(opline->op1.var); -#if 0 || 1 - if (1 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) { - zend_frameless_observed_call(execute_data); - } else -#endif - { - zend_frameless_function_0 function = (zend_frameless_function_0)ZEND_FLF_HANDLER(opline); - function(result); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + fast_long_increment_function(var_ptr); + ZEND_VM_NEXT_OPCODE(); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + ZEND_VM_TAIL_CALL(zend_post_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_post_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object; - zval *property; - zval *value; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; + zval *var_ptr; + + var_ptr = EX_VAR(opline->op1.var); SAVE_OPLINE(); - object = &EX(This); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(var_ptr); + } do { - value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_op_object; - } - if (IS_UNUSED == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; - } + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); -assign_op_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - UNDEF_RESULT(); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_incdec_typed_ref(ref, EX_VAR(opline->result.var) OPLINE_CC EXECUTE_DATA_CC); break; } } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - zend_reference *ref; - - do { - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - zptr = Z_REFVAL_P(zptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - if (prop_info) { - /* special case for typed properties */ - zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_binary_op(zptr, zptr, value OPLINE_CC); - } - } while (0); + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), zptr); - } - } - } else { - zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); - } - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + decrement_function(var_ptr); } while (0); - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + var_ptr = EX_VAR(opline->op1.var); + if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + fast_long_decrement_function(var_ptr); + ZEND_VM_NEXT_OPCODE(); + } - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_TAIL_CALL(zend_post_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; + zval *z; SAVE_OPLINE(); - object = &EX(This); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + z = EX_VAR(opline->op1.var); - do { - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto pre_incdec_object; - } - if (IS_UNUSED == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; - } + if (Z_TYPE_P(z) == IS_STRING) { + zend_string *str = Z_STR_P(z); -pre_incdec_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - UNDEF_RESULT(); - break; - } - } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); - } - } else { - zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); - } - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + if (ZSTR_LEN(str) != 0) { + zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); } - } while (0); - + } else { + zend_string *str = zval_get_string_func(z); + if (ZSTR_LEN(str) != 0) { + zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_string_release_ex(str, 0); + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; + zval *val; + uint8_t op1_type; - SAVE_OPLINE(); - object = &EX(This); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + val = EX_VAR(opline->op1.var); - do { - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto post_incdec_object; - } - if (IS_UNUSED == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; } + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } -post_incdec_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; - } - } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); - } - } else { - zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); - } - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - } while (0); + SAVE_OPLINE(); + op1_type = IS_CV; + if (i_zend_is_true(val)) { + opline++; + } else { + opline = OP_JMP_ADDR(opline, opline->op2); + } + if (op1_type & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_nogc(val); + } + ZEND_VM_JMP(opline); +} +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val; + uint8_t op1_type; + val = EX_VAR(opline->op1.var); + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + } + ZEND_VM_NEXT_OPCODE(); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + SAVE_OPLINE(); + op1_type = IS_CV; + if (i_zend_is_true(val)) { + opline = OP_JMP_ADDR(opline, opline->op2); + } else { + opline++; + } + if (op1_type & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_nogc(val); + } + ZEND_VM_JMP(opline); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - void **cache_slot = NULL; + zval *val; + bool ret; - SAVE_OPLINE(); - container = &EX(This); + val = EX_VAR(opline->op1.var); - if (IS_UNUSED == IS_CONST || - (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - break; - } - } - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); } - zend_wrong_property_read(container, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_r_finish; - } while (0); + } + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; + SAVE_OPLINE(); + ret = i_zend_is_true(val); - if (IS_CV == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + if (ret) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + opline++; + } else { + ZVAL_FALSE(EX_VAR(opline->result.var)); + opline = OP_JMP_ADDR(opline, opline->op2); + } + ZEND_VM_JMP(opline); +} - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_r_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { -fetch_obj_r_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - prop_offset = prop_info->offset; - goto fetch_obj_r_simple; - } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { - zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; - ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); - ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPNZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val; + bool ret; - uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (IS_UNUSED & IS_CV) { - GC_ADDREF(zobj); - } - if (IS_UNUSED & (IS_CV|IS_VAR|IS_TMP_VAR)) { - call_info |= ZEND_CALL_RELEASE_THIS; - } - zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); - call->prev_execute_data = execute_data; - call->call = NULL; - call->return_value = EX_VAR(opline->result.var); - call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); + val = EX_VAR(opline->op1.var); - execute_data = call; - EG(current_execute_data) = execute_data; - zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } -#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) - opline = hook->op_array.opcodes; -#else - EX(opline) = hook->op_array.opcodes; -#endif - LOAD_OPLINE_EX(); + SAVE_OPLINE(); + ret = i_zend_is_true(val); + if (ret) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + opline = OP_JMP_ADDR(opline, opline->op2); + } else { + ZVAL_FALSE(EX_VAR(opline->result.var)); + opline++; + } + ZEND_VM_JMP(opline); +} +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *retval_ptr; + zval *return_value; - ZEND_VM_ENTER_EX(); - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + retval_ptr = EX_VAR(opline->op1.var); + return_value = EX(return_value); - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; - } + + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) { + SAVE_OPLINE(); + retval_ptr = ZVAL_UNDEFINED_OP1(); + if (return_value) { + ZVAL_NULL(return_value); + } + } else if (!return_value) { + if (IS_CV & (IS_VAR|IS_TMP_VAR)) { + if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) { + SAVE_OPLINE(); + rc_dtor_func(Z_COUNTED_P(retval_ptr)); + } + } + } else { + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { + ZVAL_COPY_VALUE(return_value, retval_ptr); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) { + Z_ADDREF_P(return_value); + } + } + } else if (IS_CV == IS_CV) { + do { + if (Z_OPT_REFCOUNTED_P(retval_ptr)) { + if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { + if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + ZVAL_COPY_VALUE(return_value, retval_ptr); + if (GC_MAY_LEAK(ref)) { + SAVE_OPLINE(); + gc_possible_root(ref); } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; + ZVAL_NULL(retval_ptr); + break; } else { - goto fetch_obj_r_fast_copy; + Z_ADDREF_P(retval_ptr); + } + } else { + retval_ptr = Z_REFVAL_P(retval_ptr); + if (Z_OPT_REFCOUNTED_P(retval_ptr)) { + Z_ADDREF_P(retval_ptr); } } } - } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; - } - } - -#if ZEND_DEBUG - /* For non-standard object handlers, verify a declared property type in debug builds. - * Fetch prop_info before calling read_property(), as it may deallocate the object. */ - zend_property_info *prop_info = NULL; - if (zobj->handlers->read_property != zend_std_read_property) { - prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); - } -#endif - retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); -#if ZEND_DEBUG - if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { - ZVAL_OPT_DEREF(retval); - zend_verify_property_type(prop_info, retval, /* strict */ true); - } -#endif + ZVAL_COPY_VALUE(return_value, retval_ptr); + } while (0); + } else /* if (IS_CV == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(retval_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + retval_ptr = Z_REFVAL_P(retval_ptr); + ZVAL_COPY_VALUE(return_value, retval_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { + Z_ADDREF_P(retval_ptr); + } + } else { + ZVAL_COPY_VALUE(return_value, retval_ptr); + } } + } - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_r_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } - } while (0); -fetch_obj_r_finish: - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *property, *container, *result; + zval *retval_ptr; + zval *return_value; + SAVE_OPLINE(); - container = &EX(This); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address( - result, container, IS_UNUSED, property, IS_CV, - ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); + return_value = EX(return_value); - if (IS_UNUSED == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + do { + if ((IS_CV & (IS_CONST|IS_TMP_VAR)) || + (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { + /* Not supposed to happen, but we'll allow it */ + zend_error(E_NOTICE, "Only variable references should be returned by reference"); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *property, *container, *result; + retval_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + if (!return_value) { - SAVE_OPLINE(); - container = &EX(This); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + } else { + if (IS_CV == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) { + ZVAL_COPY_VALUE(return_value, retval_ptr); + break; + } + + ZVAL_NEW_REF(return_value, retval_ptr); + if (IS_CV == IS_CONST) { + Z_TRY_ADDREF_P(retval_ptr); + } + } + break; + } - if (IS_UNUSED == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + retval_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + + if (IS_CV == IS_VAR) { + ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) { + zend_error(E_NOTICE, "Only variable references should be returned by reference"); + if (return_value) { + ZVAL_NEW_REF(return_value, retval_ptr); + } else { + + + } + break; + } + } + + if (return_value) { + if (Z_ISREF_P(retval_ptr)) { + Z_ADDREF_P(retval_ptr); + } else { + ZVAL_MAKE_REF_EX(retval_ptr, 2); + } + ZVAL_REF(return_value, Z_REF_P(retval_ptr)); + } + + + } while (0); + + + + + // FIXME: Don't create the ref in the first place? + zend_return_unwrap_ref(execute_data, return_value); + + ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GENERATOR_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - void **cache_slot = NULL; + zval *retval; + + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); SAVE_OPLINE(); - container = &EX(This); + retval = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - if (IS_UNUSED == IS_CONST || - (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - break; - } + /* Copy return value into generator->retval */ + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { + ZVAL_COPY_VALUE(&generator->retval, retval); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) { + Z_ADDREF(generator->retval); } - if (IS_CV == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); + } + } else if (IS_CV == IS_CV) { + ZVAL_COPY_DEREF(&generator->retval, retval); + } else /* if (IS_CV == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_refcounted *ref = Z_COUNTED_P(retval); + + retval = Z_REFVAL_P(retval); + ZVAL_COPY_VALUE(&generator->retval, retval); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(retval)) { + Z_ADDREF_P(retval); } - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_is_finish; - } while (0); + } else { + ZVAL_COPY_VALUE(&generator->retval, retval); + } } - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; - if (IS_CV == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value); + EG(current_execute_data) = EX(prev_execute_data); - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + /* Close the generator to free up resources */ + zend_generator_close(generator, 1); - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_is_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { -fetch_obj_is_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - goto fetch_obj_is_simple; - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + /* Pass execution back to handling code */ + ZEND_VM_RETURN(); +} - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || (IS_UNUSED & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } + SAVE_OPLINE(); + value = EX_VAR(opline->op1.var); + + do { + if (IS_CV == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + value = Z_REFVAL_P(value); + if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { + break; } } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } - } - - retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); + zend_throw_error(NULL, "Can only throw objects"); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_is_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); + HANDLE_EXCEPTION(); } } while (0); -fetch_obj_is_finish: - - + zend_exception_save(); + Z_TRY_ADDREF_P(value); + zend_throw_exception_object(value); + zend_exception_restore(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + HANDLE_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_USER_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if 0 USE_OPLINE -#endif + zval *arg, *param; - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - /* Behave like FETCH_OBJ_W */ - if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + SAVE_OPLINE(); + + arg = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + param = ZEND_CALL_VAR(EX(call), opline->result.var); + if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) { + zend_param_must_be_ref(EX(call)->func, opline->op2.num); + Z_TRY_ADDREF_P(arg); + ZVAL_NEW_REF(param, arg); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZVAL_COPY(param, arg); } + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container, *property, *result; + zval *val; - SAVE_OPLINE(); - container = &EX(This); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + val = EX_VAR(opline->op1.var); + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + /* The result and op1 can be the same cv zval */ + const uint32_t orig_val_type = Z_TYPE_INFO_P(val); + ZVAL_FALSE(EX_VAR(opline->result.var)); + if (IS_CV == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } else { + SAVE_OPLINE(); + ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val)); - if (IS_UNUSED == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; + zval *obj; zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; + zend_class_entry *ce, *scope; + zend_function *clone; + zend_object_clone_obj_t clone_call; SAVE_OPLINE(); - object = &EX(This); - value = RT_CONSTANT((opline+1), (opline+1)->op1); + obj = EX_VAR(opline->op1.var); - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; + /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. + * The OPcode intentionally does not support a clone-with property list to keep it simple. */ + + do { + if (IS_CV == IS_CONST || + (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) { + obj = Z_REFVAL_P(obj); + if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) { + break; + } + } + ZVAL_UNDEF(EX_VAR(opline->result.var)); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj)); + + + HANDLE_EXCEPTION(); } - zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; + } while (0); + + zobj = Z_OBJ_P(obj); + ce = zobj->ce; + clone = ce->clone; + clone_call = zobj->handlers->clone_obj; + if (UNEXPECTED(clone_call == NULL)) { + zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); + + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; + if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) { + scope = EX(func)->op_array.scope; + ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC)); + if (!zend_check_method_accessible(clone, scope)) { + zend_bad_method_call(clone, clone->common.function_name, scope); - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CONST != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CONST == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_CONST == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - - - UNDEF_RESULT(); - goto exit_assign_obj; + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_DEREF(value); - } + ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj)); - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *expr; + zval *result = EX_VAR(opline->result.var); + SAVE_OPLINE(); + expr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + + switch (opline->extended_value) { + case IS_LONG: + ZVAL_LONG(result, zval_get_long(expr)); + break; + case IS_DOUBLE: + ZVAL_DOUBLE(result, zval_get_double(expr)); + break; + case IS_STRING: + ZVAL_STR(result, zval_get_string(expr)); + break; + default: + ZEND_ASSERT(opline->extended_value != _IS_BOOL && "Must use ZEND_BOOL instead"); + if (IS_CV & (IS_VAR|IS_CV)) { + ZVAL_DEREF(expr); + } + /* If value is already of correct type, return it directly */ + if (Z_TYPE_P(expr) == opline->extended_value) { + ZVAL_COPY_VALUE(result, expr); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); + } else if (IS_CV != IS_TMP_VAR) { + if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); + } -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + if (opline->extended_value == IS_ARRAY) { + zend_cast_zval_to_array(result, expr, IS_CV); + } else { + ZEND_ASSERT(opline->extended_value == IS_OBJECT); + zend_cast_zval_to_object(result, expr, IS_CV); + } + } - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; + zend_op_array *new_op_array; + zval *inc_filename; SAVE_OPLINE(); - object = &EX(This); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + inc_filename = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + new_op_array = zend_include_or_eval(inc_filename, opline->extended_value); + if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; + + if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) { + destroy_op_array(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); } - zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else if (new_op_array == ZEND_FAKE_OP_ARRAY) { + if (RETURN_VALUE_USED(opline)) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + } + } else if (UNEXPECTED(new_op_array == NULL)) { + if (RETURN_VALUE_USED(opline)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + } + } else if (new_op_array->last == 1 + && new_op_array->opcodes[0].opcode == ZEND_RETURN + && new_op_array->opcodes[0].op1_type == IS_CONST + && EXPECTED(zend_execute_ex == execute_ex)) { + if (RETURN_VALUE_USED(opline)) { + const zend_op *op = new_op_array->opcodes; -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; + ZVAL_COPY(EX_VAR(opline->result.var), RT_CONSTANT(op, op->op1)); + } + zend_destroy_static_vars(new_op_array); + destroy_op_array(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); + } else { + zval *return_value = NULL; + zend_execute_data *call; + if (RETURN_VALUE_USED(opline)) { + return_value = EX_VAR(opline->result.var); + } - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + new_op_array->scope = EX(func)->op_array.scope; -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } + call = zend_vm_stack_push_call_frame( + (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, + (zend_function*)new_op_array, 0, + Z_PTR(EX(This))); - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_TMP_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_TMP_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_TMP_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; + if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { + call->symbol_table = EX(symbol_table); + } else { + call->symbol_table = zend_rebuild_symbol_table(); } - } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_DEREF(value); - } + call->prev_execute_data = execute_data; + i_init_code_execute_data(call, new_op_array, return_value); - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + if (EXPECTED(zend_execute_ex == execute_ex)) { -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } + + ZEND_VM_ENTER(); + } else { + ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); + zend_execute_ex(call); + zend_vm_stack_free_call_frame(call); + } + + zend_destroy_static_vars(new_op_array); + destroy_op_array(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + } - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_NEXT_OPCODE(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; + zval *array_ptr, *result; SAVE_OPLINE(); - object = &EX(This); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; + array_ptr = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { + result = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(result, array_ptr); + if (IS_CV != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) { + Z_ADDREF_P(array_ptr); } - zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } + Z_FE_POS_P(result) = 0; -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + ZEND_VM_NEXT_OPCODE(); + } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { + zend_object *zobj = Z_OBJ_P(array_ptr); + if (!zobj->ce->get_iterator) { + if (UNEXPECTED(zend_object_is_lazy(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (UNEXPECTED(EG(exception))) { + UNDEF_RESULT(); -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; + HANDLE_EXCEPTION(); } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; + } + HashTable *properties = zobj->properties; + if (properties) { + if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(properties); } - goto assign_obj_simple; + properties = zobj->properties = zend_array_dup(properties); } - /* Fall through to write_property for hooks. */ + } else { + properties = zobj->handlers->get_properties(zobj); } - } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } + result = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(result, array_ptr); + if (IS_CV != IS_TMP_VAR) { + Z_ADDREF_P(array_ptr); + } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + if (zend_hash_num_elements(properties) == 0) { + Z_FE_ITER_P(result) = (uint32_t) -1; - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + } + + Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } else if (is_empty) { + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } + } else { + zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; + + + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + } } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; + zval *array_ptr, *array_ref; SAVE_OPLINE(); - object = &EX(This); - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; + if (IS_CV == IS_VAR || IS_CV == IS_CV) { + array_ref = array_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(array_ref)) { + array_ptr = Z_REFVAL_P(array_ref); } - zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; + } else { + array_ref = array_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); } -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; + if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { + if (IS_CV == IS_VAR || IS_CV == IS_CV) { + if (array_ptr == array_ref) { + ZVAL_NEW_REF(array_ref, array_ref); + array_ptr = Z_REFVAL_P(array_ref); + } + Z_ADDREF_P(array_ref); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); + } else { + array_ref = EX_VAR(opline->result.var); + ZVAL_NEW_REF(array_ref, array_ptr); + array_ptr = Z_REFVAL_P(array_ref); + } + if (IS_CV == IS_CONST) { + ZVAL_ARR(array_ptr, zend_array_dup(Z_ARRVAL_P(array_ptr))); + } else { + SEPARATE_ARRAY(array_ptr); + } + Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0); - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } + ZEND_VM_NEXT_OPCODE(); + } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { + if (!Z_OBJCE_P(array_ptr)->get_iterator) { + zend_object *zobj = Z_OBJ_P(array_ptr); + HashTable *properties; + if (UNEXPECTED(zend_object_is_lazy(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (UNEXPECTED(EG(exception))) { + UNDEF_RESULT(); - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CV != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CV == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_CV == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; + + HANDLE_EXCEPTION(); } + } + if (IS_CV == IS_VAR || IS_CV == IS_CV) { + if (array_ptr == array_ref) { + ZVAL_NEW_REF(array_ref, array_ref); + array_ptr = Z_REFVAL_P(array_ref); + } + Z_ADDREF_P(array_ref); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; + array_ptr = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(array_ptr, array_ref); + } + if (Z_OBJ_P(array_ptr)->properties + && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(Z_OBJ_P(array_ptr)->properties); } - /* Fall through to write_property for hooks. */ + Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); } - } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - - - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_DEREF(value); - } + properties = Z_OBJPROP_P(array_ptr); + if (zend_hash_num_elements(properties) == 0) { + Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1; - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + } -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } + Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } else if (is_empty) { + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } + } else { + zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + } } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *property, *container, *value_ptr; + zval *value; + zend_reference *ref = NULL; + bool ret; SAVE_OPLINE(); + value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - container = &EX(This); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(value)) { + if (IS_CV == IS_VAR) { + ref = Z_REF_P(value); + } + value = Z_REFVAL_P(value); + } - value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + ret = i_zend_is_true(value); - if (1) { - if (IS_UNUSED == IS_UNUSED) { - if (IS_CV == IS_CONST) { - zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } else { - if (IS_CV == IS_CONST) { - zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } - } else { - zend_assign_to_property_reference(container, IS_UNUSED, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(EG(exception))) { + + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } + if (ret) { + zval *result = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(result, value); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); + } else if (IS_CV == IS_CV) { + if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); + } else if (IS_CV == IS_VAR && ref) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(result)) { + Z_ADDREF_P(result); + } + } + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_NEXT_OPCODE(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *property, *container, *value_ptr; + zval *value; + zend_reference *ref = NULL; SAVE_OPLINE(); + value = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); - container = &EX(This); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - - value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + if (IS_CV & IS_VAR) { + ref = Z_REF_P(value); + } + value = Z_REFVAL_P(value); + } - if (1) { - if (IS_UNUSED == IS_UNUSED) { - if (IS_CV == IS_CONST) { - zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } else { - if (IS_CV == IS_CONST) { - zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + if (Z_TYPE_P(value) > IS_NULL) { + zval *result = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(result, value); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); + } else if (IS_CV == IS_CV) { + if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); + } else if ((IS_CV & IS_VAR) && ref) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(result)) { + Z_ADDREF_P(result); } } - } else { - zend_assign_to_property_reference(container, IS_UNUSED, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC); + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } - - - - - - ZEND_VM_NEXT_OPCODE_EX(1, 2); + if ((IS_CV & IS_VAR) && ref) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } + } + ZEND_VM_NEXT_OPCODE(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ROPE_INIT_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_NULL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_string **rope; - zval *var; + zval *val, *result; - /* Compiler allocates the necessary number of zval slots to keep the rope */ - rope = (zend_string**)EX_VAR(opline->result.var); - if (IS_CV == IS_CONST) { - var = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - rope[0] = Z_STR_P(var); - if (UNEXPECTED(Z_REFCOUNTED_P(var))) { - Z_ADDREF_P(var); - } - } else { - var = EX_VAR(opline->op2.var); - if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { - if (IS_CV == IS_CV) { - rope[0] = zend_string_copy(Z_STR_P(var)); - } else { - rope[0] = Z_STR_P(var); + val = EX_VAR(opline->op1.var); + + if (Z_TYPE_P(val) > IS_NULL) { + do { + if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + if (Z_TYPE_P(val) <= IS_NULL) { + + + break; + } } - } else { + ZEND_VM_NEXT_OPCODE(); + } while (0); + } + + result = EX_VAR(opline->result.var); + uint32_t short_circuiting_type = opline->extended_value & ZEND_SHORT_CIRCUITING_CHAIN_MASK; + if (EXPECTED(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { + ZVAL_NULL(result); + if (IS_CV == IS_CV + && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF) + && (opline->extended_value & ZEND_JMP_NULL_BP_VAR_IS) == 0 + ) { SAVE_OPLINE(); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); } - rope[0] = zval_get_string_func(var); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + } else if (short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { + ZVAL_FALSE(result); + } else { + ZEND_ASSERT(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); + ZVAL_TRUE(result); } - ZEND_VM_NEXT_OPCODE(); + + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zval *class_name; USE_OPLINE + zval *value; + zval *result = EX_VAR(opline->result.var); - SAVE_OPLINE(); - if (IS_CV == IS_UNUSED) { - Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num); + value = EX_VAR(opline->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(result); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else if (IS_CV == IS_CONST) { - zend_class_entry *ce = CACHED_PTR(opline->extended_value); + } - if (UNEXPECTED(ce == NULL)) { - class_name = EX_VAR(opline->op2.var); - ce = zend_fetch_class_by_name(Z_STR_P(class_name), Z_STR_P(class_name + 1), opline->op1.num); - CACHE_PTR(opline->extended_value, ce); + if (IS_CV == IS_CV) { + ZVAL_COPY_DEREF(result, value); + } else if (IS_CV == IS_VAR) { + if (UNEXPECTED(Z_ISREF_P(value))) { + ZVAL_COPY_VALUE(result, Z_REFVAL_P(value)); + if (UNEXPECTED(Z_DELREF_P(value) == 0)) { + efree_size(Z_REF_P(value), sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(result)) { + Z_ADDREF_P(result); + } + } else { + ZVAL_COPY_VALUE(result, value); } - Z_CE_P(EX_VAR(opline->result.var)) = ce; } else { - class_name = EX_VAR(opline->op2.var); -try_class_name: - if (Z_TYPE_P(class_name) == IS_OBJECT) { - Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name); - } else if (Z_TYPE_P(class_name) == IS_STRING) { - Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num); - } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) { - class_name = Z_REFVAL_P(class_name); - goto try_class_name; - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } + ZVAL_COPY_VALUE(result, value); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) { + Z_ADDREF_P(result); } - zend_throw_error(NULL, "Class name must be a valid object or a string"); } } - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_FROM_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zval *object; - zend_function *fbc; - zend_class_entry *called_scope; - zend_object *obj; - zend_execute_data *call; - uint32_t call_info; + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + zval *val; SAVE_OPLINE(); + val = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - object = &EX(This); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator"); - if (IS_CV != IS_CONST) { - function_name = EX_VAR(opline->op2.var); + + UNDEF_RESULT(); + HANDLE_EXCEPTION(); } - if (IS_CV != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { +yield_from_try_again: + if (Z_TYPE_P(val) == IS_ARRAY) { + ZVAL_COPY_VALUE(&generator->values, val); + if (Z_OPT_REFCOUNTED_P(val)) { + Z_ADDREF_P(val); + } + Z_FE_POS(generator->values) = 0; + + + } else if (IS_CV != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) { + zend_class_entry *ce = Z_OBJCE_P(val); + if (ce == zend_ce_generator) { + zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); + + Z_ADDREF_P(val); + if (UNEXPECTED(new_gen->execute_data == NULL)) { + zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); + zval_ptr_dtor(val); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else if (Z_ISUNDEF(new_gen->retval)) { + if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) { + zend_throw_error(NULL, "Impossible to yield from the Generator being currently run"); + zval_ptr_dtor(val); + UNDEF_RESULT(); HANDLE_EXCEPTION(); + } else { + zend_generator_yield_from(generator, new_gen); + } + } else { + if (RETURN_VALUE_USED(opline)) { + ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval); } + ZEND_VM_NEXT_OPCODE(); } - zend_throw_error(NULL, "Method name must be a string"); - - + } else { + zend_object_iterator *iter = ce->get_iterator(ce, val, 0); - HANDLE_EXCEPTION(); - } while (0); - } + if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) { + if (!EG(exception)) { + zend_throw_error(NULL, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name)); + } + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } - if (IS_UNUSED == IS_UNUSED) { - obj = Z_OBJ_P(object); - } else { - do { - if (IS_UNUSED != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - } else { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - zend_reference *ref = Z_REF_P(object); - - object = &ref->val; - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - if (IS_UNUSED & IS_VAR) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_ADDREF_P(object); - } - } - break; - } + iter->index = 0; + if (iter->funcs->rewind) { + iter->funcs->rewind(iter); + if (UNEXPECTED(EG(exception) != NULL)) { + OBJ_RELEASE(&iter->std); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); } - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - object = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CV != IS_CONST) { + } + ZVAL_OBJ(&generator->values, &iter->std); + } + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + goto yield_from_try_again; + } else { + zend_throw_error(NULL, "Can use \"yield from\" only with arrays and Traversables"); - } - HANDLE_EXCEPTION(); - } - } - if (IS_CV == IS_CONST) { - function_name = EX_VAR(opline->op2.var); - } - zend_invalid_method_call(object, function_name); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + /* This is the default return value + * when the expression is a Generator, it will be overwritten in zend_generator_resume() */ + if (RETURN_VALUE_USED(opline)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + /* This generator has no send target (though the generator we delegate to might have one) */ + generator->send_target = NULL; - HANDLE_EXCEPTION(); - } - } while (0); - } + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); - called_scope = obj->ce; + ZEND_VM_RETURN(); +} - if (IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else { - zend_object *orig_obj = obj; +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; - if (IS_CV == IS_CONST) { - function_name = EX_VAR(opline->op2.var); + value = EX_VAR(opline->op1.var); + if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(value); } + ZEND_VM_NEXT_OPCODE(); + } else { + bool strict; - /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); - } + if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) { + value = Z_REFVAL_P(value); + if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); - if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); - } - HANDLE_EXCEPTION(); - } - if (IS_CV == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); - } - if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ - if (GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); + ZEND_VM_NEXT_OPCODE(); } } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - } - - if (IS_CV != IS_CONST) { + SAVE_OPLINE(); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + value = ZVAL_UNDEFINED_OP1(); + } + strict = EX_USES_STRICT_TYPES(); + do { + if (EXPECTED(!strict)) { + zend_string *str; + zval tmp; - } + if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) { + zend_error(E_DEPRECATED, + "strlen(): Passing null to parameter #1 ($string) of type string is deprecated"); + ZVAL_LONG(EX_VAR(opline->result.var), 0); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + break; + } - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { - zend_objects_store_del(obj); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + ZVAL_COPY(&tmp, value); + if (zend_parse_arg_str_weak(&tmp, &str, 1)) { + ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str)); + zval_ptr_dtor(&tmp); + break; + } + zval_ptr_dtor(&tmp); } - } - /* call static method */ - obj = (zend_object*)called_scope; - call_info = ZEND_CALL_NESTED_FUNCTION; - } else if (IS_UNUSED & (IS_VAR|IS_TMP_VAR|IS_CV)) { - if (IS_UNUSED == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ - } - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; + if (!EG(exception)) { + zend_type_error("strlen(): Argument #1 ($string) must be of type string, %s given", zend_zval_value_name(value)); + } + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } while (0); } - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, obj); - call->prev_execute_data = EX(call); - EX(call) = call; - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_TYPE_CHECK_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zend_class_entry *ce; - uint32_t call_info; - zend_function *fbc; - zend_execute_data *call; - - SAVE_OPLINE(); - - if (IS_UNUSED == IS_CONST) { - /* no function found. try a static method in class */ - ce = CACHED_PTR(opline->result.num); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - + zval *value; + int result = 0; - HANDLE_EXCEPTION(); - } - if (IS_CV != IS_CONST) { - CACHE_PTR(opline->result.num, ce); - } + value = EX_VAR(opline->op1.var); + if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { +type_check_resource: + if (opline->extended_value != MAY_BE_RESOURCE + || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) { + result = 1; } - } else if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - - + } else if ((IS_CV & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) { + value = Z_REFVAL_P(value); + if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { + goto type_check_resource; + } + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + result = ((1 << IS_NULL) & opline->extended_value) != 0; + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); } + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + + + ZEND_VM_SMART_BRANCH(result, 1); } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 0); } +} - if (IS_UNUSED == IS_CONST && - IS_CV == IS_CONST && - EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { - /* nothing to do */ - } else if (IS_UNUSED != IS_CONST && - IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else if (IS_CV != IS_UNUSED) { - function_name = EX_VAR(opline->op2.var); - if (IS_CV != IS_CONST) { - if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if (IS_CV & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Method name must be a string"); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + uint32_t fetch_type; + zend_class_entry *called_scope, *scope; + USE_OPLINE + if (IS_CV != IS_UNUSED) { + SAVE_OPLINE(); + zval *op = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(Z_TYPE_P(op) != IS_OBJECT)) { + ZVAL_DEREF(op); + if (Z_TYPE_P(op) != IS_OBJECT) { + zend_type_error("Cannot use \"::class\" on %s", zend_zval_value_name(op)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } while (0); - } - } - if (ce->get_static_method) { - fbc = ce->get_static_method(ce, Z_STR_P(function_name)); - } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - } - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(ce, Z_STR_P(function_name)); + HANDLE_EXCEPTION(); } + } + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op)->name); - HANDLE_EXCEPTION(); - } - if (IS_CV == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { - CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - if (IS_CV != IS_CONST) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } - } - } else { - if (UNEXPECTED(ce->constructor == NULL)) { - zend_throw_error(NULL, "Cannot call constructor"); - HANDLE_EXCEPTION(); - } - if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { - zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); - HANDLE_EXCEPTION(); - } - fbc = ce->constructor; - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } + fetch_type = opline->op1.num; + scope = EX(func)->op_array.scope; + if (UNEXPECTED(scope == NULL)) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", + fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : + fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } - if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { - if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - ce = (zend_class_entry*)Z_OBJ(EX(This)); - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - } else { - zend_non_static_method_call(fbc); - HANDLE_EXCEPTION(); - } - } else { - /* previous opcode is ZEND_FETCH_CLASS */ - if (IS_UNUSED == IS_UNUSED - && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { + switch (fetch_type) { + case ZEND_FETCH_CLASS_SELF: + ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->name); + break; + case ZEND_FETCH_CLASS_PARENT: + if (UNEXPECTED(scope->parent == NULL)) { + SAVE_OPLINE(); + zend_throw_error(NULL, + "Cannot use \"parent\" when current class scope has no parent"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->parent->name); + break; + case ZEND_FETCH_CLASS_STATIC: if (Z_TYPE(EX(This)) == IS_OBJECT) { - ce = Z_OBJCE(EX(This)); + called_scope = Z_OBJCE(EX(This)); } else { - ce = Z_CE(EX(This)); + called_scope = Z_CE(EX(This)); } - } - call_info = ZEND_CALL_NESTED_FUNCTION; + ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name); + break; + EMPTY_SWITCH_DEFAULT_CASE() } - - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, ce); - call->prev_execute_data = EX(call); - EX(call) = call; - ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BIND_STATIC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zval *array; - uint32_t size; USE_OPLINE + HashTable *ht; + zval *value; + zval *variable_ptr; + + variable_ptr = EX_VAR(opline->op1.var); SAVE_OPLINE(); - array = EX_VAR(opline->result.var); - if (IS_UNUSED != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); - } - ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZVAL_ARR(array, zend_new_array(0)); - ZEND_VM_NEXT_OPCODE(); - } -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - zval *offset; - zend_string *name, *tmp_name; + ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr); + if (!ht) { + ht = zend_array_dup(EX(func)->op_array.static_variables); + ZEND_MAP_PTR_SET(EX(func)->op_array.static_variables_ptr, ht); + } + ZEND_ASSERT(GC_REFCOUNT(ht) == 1); - SAVE_OPLINE(); - container = &EX(This); - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + value = (zval*)((char*)ht->arData + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT))); - do { - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - if (Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (Z_TYPE_P(container) != IS_OBJECT) { - if (IS_UNUSED == IS_CV - && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - break; - } + if (opline->extended_value & ZEND_BIND_REF) { + if (UNEXPECTED(!Z_ISREF_P(value))) { + zend_reference *ref = (zend_reference*)emalloc(sizeof(zend_reference)); + GC_SET_REFCOUNT(ref, 2); + GC_TYPE_INFO(ref) = GC_REFERENCE; + if (opline->op2_type == IS_UNUSED) { + ZVAL_COPY_VALUE(&ref->val, value); } else { - break; + ZEND_ASSERT(!Z_REFCOUNTED_P(value)); + ZVAL_COPY(&ref->val, get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R)); + FREE_OP(opline->op2_type, opline->op2.var); } - } - if (IS_CV == IS_CONST) { - name = Z_STR_P(offset); + ref->sources.ptr = NULL; + Z_REF_P(value) = ref; + Z_TYPE_INFO_P(value) = IS_REFERENCE_EX; + i_zval_ptr_dtor(variable_ptr); + ZVAL_REF(variable_ptr, ref); } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - break; + Z_ADDREF_P(value); + i_zval_ptr_dtor(variable_ptr); + ZVAL_REF(variable_ptr, Z_REF_P(value)); + if (opline->op2_type != IS_UNUSED) { + FREE_OP(opline->op2_type, opline->op2.var); } } - Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - } while (0); - - - + } else { + i_zval_ptr_dtor(variable_ptr); + ZVAL_COPY(variable_ptr, value); + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BIND_INIT_STATIC_OR_JMP_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - int result; - zval *offset; - zend_string *name, *tmp_name; + HashTable *ht; + zval *value; + zval *variable_ptr; - SAVE_OPLINE(); - container = &EX(This); - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = EX_VAR(opline->op1.var); - if (IS_UNUSED == IS_CONST || - (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } - } else { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } + ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr); + if (!ht) { + ZEND_VM_NEXT_OPCODE(); } + ZEND_ASSERT(GC_REFCOUNT(ht) == 1); - if (IS_CV == IS_CONST) { - name = Z_STR_P(offset); + value = (zval*)((char*)ht->arData + opline->extended_value); + if (Z_TYPE_P(value) == IS_NULL) { + ZEND_VM_NEXT_OPCODE(); } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - result = 0; - goto isset_object_finish; - } - } - - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + SAVE_OPLINE(); + zval_ptr_dtor(variable_ptr); + ZEND_ASSERT(Z_TYPE_P(value) == IS_REFERENCE); + Z_ADDREF_P(value); + ZVAL_REF(variable_ptr, Z_REF_P(value)); + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 1); } - -isset_object_finish: - - - - - ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *var_ptr; - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - - SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); - - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); - - /* Set the new yielded value */ - if (IS_UNUSED != IS_UNUSED) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_UNUSED & (IS_CONST|IS_TMP_VAR)) { - zval *value; - - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - - value = NULL; - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_UNUSED == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } - } else { - zval *value_ptr = NULL; - - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - do { - if (IS_UNUSED == IS_VAR) { - ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION - && !Z_ISREF_P(value_ptr)) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - ZVAL_COPY(&generator->value, value_ptr); - break; - } - } - if (Z_ISREF_P(value_ptr)) { - Z_ADDREF_P(value_ptr); - } else { - ZVAL_MAKE_REF_EX(value_ptr, 2); - } - ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); - } while (0); - - - } - } else { - zval *value = NULL; - - /* Consts, temporary variables and references need copying */ - if (IS_UNUSED == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } else if (IS_UNUSED == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - - - } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_UNUSED == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } - } - } - } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); - } - - /* Set the new yielded key */ - if (IS_CV != IS_UNUSED) { - zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if ((IS_CV & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { - key = Z_REFVAL_P(key); - } - ZVAL_COPY(&generator->key, key); - - - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); - } - } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); - } - - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); - } else { - generator->send_target = NULL; + var_ptr = EX_VAR(opline->op1.var); + Z_LVAL_P(var_ptr)++; + if (UNEXPECTED(0)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); } - - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); - - ZEND_VM_RETURN(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_NOT_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; - - val = EX_VAR(opline->op1.var); - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - /* The result and op1 can be the same cv zval */ - const uint32_t orig_val_type = Z_TYPE_INFO_P(val); - ZVAL_TRUE(EX_VAR(opline->result.var)); - if (IS_CV == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - } else { - SAVE_OPLINE(); - ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val)); - + zval *var_ptr; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + var_ptr = EX_VAR(opline->op1.var); + Z_LVAL_P(var_ptr)++; + if (UNEXPECTED(1)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); } ZEND_VM_NEXT_OPCODE(); } -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_pre_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *var_ptr; var_ptr = EX_VAR(opline->op1.var); - - SAVE_OPLINE(); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(var_ptr); + fast_long_increment_function(var_ptr); + if (UNEXPECTED(0)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); } + ZEND_VM_NEXT_OPCODE(); +} - do { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_incdec_typed_ref(ref, NULL OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - increment_function(var_ptr); - } while (0); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + var_ptr = EX_VAR(opline->op1.var); + fast_long_increment_function(var_ptr); + if (UNEXPECTED(1)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); } - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *var_ptr; var_ptr = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - fast_long_increment_function(var_ptr); - if (UNEXPECTED(0)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - } - ZEND_VM_NEXT_OPCODE(); + Z_LVAL_P(var_ptr)--; + if (UNEXPECTED(0)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); } - - ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *var_ptr; var_ptr = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - fast_long_increment_function(var_ptr); - if (UNEXPECTED(1)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - } - ZEND_VM_NEXT_OPCODE(); + Z_LVAL_P(var_ptr)--; + if (UNEXPECTED(1)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); } - - ZEND_VM_TAIL_CALL(zend_pre_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_NEXT_OPCODE(); } -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_pre_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *var_ptr; var_ptr = EX_VAR(opline->op1.var); - - SAVE_OPLINE(); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(var_ptr); + fast_long_decrement_function(var_ptr); + if (UNEXPECTED(0)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); } + ZEND_VM_NEXT_OPCODE(); +} - do { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_incdec_typed_ref(ref, NULL OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - decrement_function(var_ptr); - } while (0); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + var_ptr = EX_VAR(opline->op1.var); + fast_long_decrement_function(var_ptr); + if (UNEXPECTED(1)) { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); } + ZEND_VM_NEXT_OPCODE(); +} +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + var_ptr = EX_VAR(opline->op1.var); + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + Z_LVAL_P(var_ptr)++; + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_LONG_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *var_ptr; var_ptr = EX_VAR(opline->op1.var); + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + fast_long_increment_function(var_ptr); + ZEND_VM_NEXT_OPCODE(); +} - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - fast_long_decrement_function(var_ptr); - if (UNEXPECTED(0)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - } - ZEND_VM_NEXT_OPCODE(); - } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; - ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + var_ptr = EX_VAR(opline->op1.var); + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + Z_LVAL_P(var_ptr)--; + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_DEC_LONG_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *var_ptr; var_ptr = EX_VAR(opline->op1.var); + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + fast_long_decrement_function(var_ptr); + ZEND_VM_NEXT_OPCODE(); +} - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - fast_long_decrement_function(var_ptr); - if (UNEXPECTED(1)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - } - ZEND_VM_NEXT_OPCODE(); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SIMPLE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varptr, *arg; + + varptr = EX_VAR(opline->op1.var); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + + if (IS_CV == IS_CV) { + ZVAL_COPY(arg, varptr); + } else /* if (IS_CV == IS_VAR) */ { + ZVAL_COPY_VALUE(arg, varptr); } - ZEND_VM_TAIL_CALL(zend_pre_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_NEXT_OPCODE(); } -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_post_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); + zval *op1, *op2; SAVE_OPLINE(); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(var_ptr); - } - - do { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); + op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + div_function(EX_VAR(opline->result.var), op1, op2); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_incdec_typed_ref(ref, EX_VAR(opline->result.var) OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - increment_function(var_ptr); - } while (0); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; + zval *op1, *op2; - var_ptr = EX_VAR(opline->op1.var); + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + pow_function(EX_VAR(opline->result.var), op1, op2); - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - fast_long_increment_function(var_ptr); - ZEND_VM_NEXT_OPCODE(); - } - ZEND_VM_TAIL_CALL(zend_post_inc_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV zend_post_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; + zval *op1, *op2; - var_ptr = EX_VAR(opline->op1.var); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); - SAVE_OPLINE(); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(var_ptr); - } + if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); - do { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); + if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else if (IS_CV != IS_CONST && IS_CV != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_incdec_typed_ref(ref, EX_VAR(opline->result.var) OPLINE_CC EXECUTE_DATA_CC); - break; + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { + zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); } } - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - - decrement_function(var_ptr); - } while (0); + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = ZVAL_UNDEFINED_OP1(); + } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = ZVAL_UNDEFINED_OP2(); + } + concat_function(EX_VAR(opline->result.var), op1, op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - var_ptr = EX_VAR(opline->op1.var); - if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - fast_long_decrement_function(var_ptr); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - - ZEND_VM_TAIL_CALL(zend_post_dec_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ECHO_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *z; + zval *op1, *op2; + bool result; SAVE_OPLINE(); - z = EX_VAR(opline->op1.var); - - if (Z_TYPE_P(z) == IS_STRING) { - zend_string *str = Z_STR_P(z); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + result = fast_is_identical_function(op1, op2); - if (ZSTR_LEN(str) != 0) { - zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); - } - } else { - zend_string *str = zval_get_string_func(z); - if (ZSTR_LEN(str) != 0) { - zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); - } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_string_release_ex(str, 0); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; - uint8_t op1_type; + zval *op1, *op2; + bool result; - val = EX_VAR(opline->op1.var); + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + result = fast_is_not_identical_function(op1, op2); - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - SAVE_OPLINE(); - op1_type = IS_CV; - if (i_zend_is_true(val)) { - opline++; - } else { - opline = OP_JMP_ADDR(opline, opline->op2); - } - if (op1_type & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_nogc(val); - } - ZEND_VM_JMP(opline); + + + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPNZ_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; - uint8_t op1_type; - - val = EX_VAR(opline->op1.var); + zval *op1, *op2; + double d1, d2; - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; } } - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - op1_type = IS_CV; - if (i_zend_is_true(val)) { - opline = OP_JMP_ADDR(opline, opline->op2); - } else { - opline++; - } - if (op1_type & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_nogc(val); } - ZEND_VM_JMP(opline); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; - bool ret; - - val = EX_VAR(opline->op1.var); + zval *op1, *op2; + double d1, d2; - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; } } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - - SAVE_OPLINE(); - ret = i_zend_is_true(val); - - - if (ret) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - opline++; - } else { - ZVAL_FALSE(EX_VAR(opline->result.var)); - opline = OP_JMP_ADDR(opline, opline->op2); } - ZEND_VM_JMP(opline); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMPNZ_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; - bool ret; - - val = EX_VAR(opline->op1.var); + zval *op1, *op2; + double d1, d2; - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_NEXT_OPCODE(); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; + } } } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} - SAVE_OPLINE(); - ret = i_zend_is_true(val); - +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; - if (ret) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - opline = OP_JMP_ADDR(opline, opline->op2); - } else { - ZVAL_FALSE(EX_VAR(opline->result.var)); - opline++; + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } } - ZEND_VM_JMP(opline); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *retval_ptr; - zval *return_value; - - - retval_ptr = EX_VAR(opline->op1.var); - return_value = EX(return_value); - + zval *op1, *op2; + double d1, d2; - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) { - SAVE_OPLINE(); - retval_ptr = ZVAL_UNDEFINED_OP1(); - if (return_value) { - ZVAL_NULL(return_value); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; } - } else if (!return_value) { - if (IS_CV & (IS_VAR|IS_TMP_VAR)) { - if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) { - SAVE_OPLINE(); - rc_dtor_func(Z_COUNTED_P(retval_ptr)); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; } - } else { - if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) { - Z_ADDREF_P(return_value); - } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); } - } else if (IS_CV == IS_CV) { - do { - if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { - zend_refcounted *ref = Z_COUNTED_P(retval_ptr); - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (GC_MAY_LEAK(ref)) { - SAVE_OPLINE(); - gc_possible_root(ref); - } - ZVAL_NULL(retval_ptr); - break; - } else { - Z_ADDREF_P(retval_ptr); - } - } else { - retval_ptr = Z_REFVAL_P(retval_ptr); - if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } - } - } - ZVAL_COPY_VALUE(return_value, retval_ptr); - } while (0); - } else /* if (IS_CV == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(retval_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(retval_ptr); - - retval_ptr = Z_REFVAL_P(retval_ptr); - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; } else { - ZVAL_COPY_VALUE(return_value, retval_ptr); + goto is_not_equal_false; } } } - - - - - - - ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *retval_ptr; - zval *return_value; - - - SAVE_OPLINE(); - - return_value = EX(return_value); - - - do { - if ((IS_CV & (IS_CONST|IS_TMP_VAR)) || - (IS_CV == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { - /* Not supposed to happen, but we'll allow it */ - zend_error(E_NOTICE, "Only variable references should be returned by reference"); - - retval_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - if (!return_value) { - + zval *op1, *op2; + double d1, d2; + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); } else { - if (IS_CV == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) { - ZVAL_COPY_VALUE(return_value, retval_ptr); - break; - } - - ZVAL_NEW_REF(return_value, retval_ptr); - if (IS_CV == IS_CONST) { - Z_TRY_ADDREF_P(retval_ptr); - } +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); } - break; + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; } - - retval_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_VAR) { - ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) { - zend_error(E_NOTICE, "Only variable references should be returned by reference"); - if (return_value) { - ZVAL_NEW_REF(return_value, retval_ptr); - } else { - - - } - break; + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; } - - if (return_value) { - if (Z_ISREF_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; } else { - ZVAL_MAKE_REF_EX(retval_ptr, 2); + goto is_not_equal_false; } - ZVAL_REF(return_value, Z_REF_P(retval_ptr)); } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; - } while (0); + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + compare_function(EX_VAR(opline->result.var), op1, op2); - ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GENERATOR_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_XOR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *retval; - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + zval *op1, *op2; SAVE_OPLINE(); - retval = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + boolean_xor_function(EX_VAR(opline->result.var), op1, op2); - /* Copy return value into generator->retval */ - if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { - ZVAL_COPY_VALUE(&generator->retval, retval); - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) { - Z_ADDREF(generator->retval); + + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *object; + zval *property; + zval *value; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; + + SAVE_OPLINE(); + object = EX_VAR(opline->op1.var); + property = RT_CONSTANT(opline, opline->op2); + + do { + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); + + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_op_object; + } + if (IS_CV == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; } - } else if (IS_CV == IS_CV) { - ZVAL_COPY_DEREF(&generator->retval, retval); - } else /* if (IS_CV == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_refcounted *ref = Z_COUNTED_P(retval); - retval = Z_REFVAL_P(retval); - ZVAL_COPY_VALUE(&generator->retval, retval); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(retval)) { - Z_ADDREF_P(retval); +assign_op_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + UNDEF_RESULT(); + break; + } + } + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + zend_reference *ref; + + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + zptr = Z_REFVAL_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; + } + } + + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + if (prop_info) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_binary_op(zptr, zptr, value OPLINE_CC); + } + } while (0); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), zptr); + } } } else { - ZVAL_COPY_VALUE(&generator->retval, retval); + zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); } - } + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); + + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - EG(current_execute_data) = EX(prev_execute_data); - /* Close the generator to free up resources */ - zend_generator_close(generator, 1); - /* Pass execution back to handling code */ - ZEND_VM_RETURN(); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; + zval *var_ptr; + zval *value, *container, *dim; + HashTable *ht; SAVE_OPLINE(); - value = EX_VAR(opline->op1.var); + container = EX_VAR(opline->op1.var); - do { - if (IS_CV == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - value = Z_REFVAL_P(value); - if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +assign_dim_op_array: + SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); +assign_dim_op_new_array: + dim = RT_CONSTANT(opline, opline->op2); + if (IS_CONST == IS_UNUSED) { + var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); + if (UNEXPECTED(!var_ptr)) { + zend_cannot_add_element(); + goto assign_dim_op_ret_null; + } + } else { + if (IS_CONST == IS_CONST) { + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); + } else { + var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(!var_ptr)) { + goto assign_dim_op_ret_null; + } + } + + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); + + do { + if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); break; } } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } + zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); + } while (0); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + } + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + } else { + if (EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto assign_dim_op_array; } - zend_throw_error(NULL, "Can only throw objects"); + } + + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = RT_CONSTANT(opline, opline->op2); + if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + uint8_t old_type; - HANDLE_EXCEPTION(); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + ht = zend_new_array(8); + old_type = Z_TYPE_P(container); + ZVAL_ARR(container, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_op_ret_null; + } + } + goto assign_dim_op_new_array; + } else { + dim = RT_CONSTANT(opline, opline->op2); + zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); +assign_dim_op_ret_null: + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } - } while (0); + } - zend_exception_save(); - Z_TRY_ADDREF_P(value); - zend_throw_exception_object(value); - zend_exception_restore(); - HANDLE_EXCEPTION(); + + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_USER_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *arg, *param; + zval *var_ptr; + zval *value; SAVE_OPLINE(); + value = RT_CONSTANT(opline, opline->op2); + var_ptr = _get_zval_ptr_cv_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC); - arg = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - param = ZEND_CALL_VAR(EX(call), opline->result.var); - if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) { - zend_param_must_be_ref(EX(call)->func, opline->op2.num); - Z_TRY_ADDREF_P(arg); - ZVAL_NEW_REF(param, arg); - } else { - ZVAL_COPY(param, arg); + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; + } + } + zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); + } while (0); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; - val = EX_VAR(opline->op1.var); - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - /* The result and op1 can be the same cv zval */ - const uint32_t orig_val_type = Z_TYPE_INFO_P(val); - ZVAL_FALSE(EX_VAR(opline->result.var)); - if (IS_CV == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + SAVE_OPLINE(); + object = EX_VAR(opline->op1.var); + property = RT_CONSTANT(opline, opline->op2); + + do { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto pre_incdec_object; + } + if (IS_CV == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; } - } else { - SAVE_OPLINE(); - ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val)); +pre_incdec_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + UNDEF_RESULT(); + break; + } + } + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); + zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); + } + } else { + zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); + } + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); + + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *obj; + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; zend_object *zobj; - zend_class_entry *ce, *scope; - zend_function *clone; - zend_object_clone_obj_t clone_call; + zend_string *name, *tmp_name; SAVE_OPLINE(); - obj = EX_VAR(opline->op1.var); - - /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. - * The OPcode intentionally does not support a clone-with property list to keep it simple. */ + object = EX_VAR(opline->op1.var); + property = RT_CONSTANT(opline, opline->op2); do { - if (IS_CV == IS_CONST || - (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) { - obj = Z_REFVAL_P(obj); - if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) { - break; - } + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto post_incdec_object; } - ZVAL_UNDEF(EX_VAR(opline->result.var)); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { + if (IS_CV == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } } - zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj)); - + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } - HANDLE_EXCEPTION(); +post_incdec_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; + } + } + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); + } + } else { + zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); + } + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } } while (0); - zobj = Z_OBJ_P(obj); - ce = zobj->ce; - clone = ce->clone; - clone_call = zobj->handlers->clone_obj; - if (UNEXPECTED(clone_call == NULL)) { - zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) { - scope = EX(func)->op_array.scope; - ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC)); - if (!zend_check_method_accessible(clone, scope)) { - zend_bad_method_call(clone, clone->common.function_name, scope); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container, *dim, *value; - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + if (IS_CV & (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 = RT_CONSTANT(opline, opline->op2); + if (IS_CV != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R EXECUTE_DATA_CC); + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } else if (IS_CV == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; + } + } else { +fetch_dim_r_slow: + if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); } + } else { + zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); } - ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *expr; - zval *result = EX_VAR(opline->result.var); + zval *container; SAVE_OPLINE(); - expr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + container = EX_VAR(opline->op1.var); + zend_fetch_dimension_address_W(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); - switch (opline->extended_value) { - case IS_LONG: - ZVAL_LONG(result, zval_get_long(expr)); - break; - case IS_DOUBLE: - ZVAL_DOUBLE(result, zval_get_double(expr)); - break; - case IS_STRING: - ZVAL_STR(result, zval_get_string(expr)); - break; - default: - ZEND_ASSERT(opline->extended_value != _IS_BOOL && "Must use ZEND_BOOL instead"); - if (IS_CV & (IS_VAR|IS_CV)) { - ZVAL_DEREF(expr); - } - /* If value is already of correct type, return it directly */ - if (Z_TYPE_P(expr) == opline->extended_value) { - ZVAL_COPY_VALUE(result, expr); - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_CV != IS_TMP_VAR) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); - } + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; - if (opline->extended_value == IS_ARRAY) { - zend_cast_zval_to_array(result, expr, IS_CV); - } else { - ZEND_ASSERT(opline->extended_value == IS_OBJECT); - zend_cast_zval_to_object(result, expr, IS_CV); - } - } + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + zend_fetch_dimension_address_RW(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_op_array *new_op_array; - zval *inc_filename; + zval *container; SAVE_OPLINE(); - inc_filename = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - new_op_array = zend_include_or_eval(inc_filename, opline->extended_value); - if (UNEXPECTED(EG(exception) != NULL)) { + container = EX_VAR(opline->op1.var); + /* 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, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); - if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) { - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); - } - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else if (new_op_array == ZEND_FAKE_OP_ARRAY) { - if (RETURN_VALUE_USED(opline)) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - } - } else if (UNEXPECTED(new_op_array == NULL)) { - if (RETURN_VALUE_USED(opline)) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - } - } else if (new_op_array->last == 1 - && new_op_array->opcodes[0].opcode == ZEND_RETURN - && new_op_array->opcodes[0].op1_type == IS_CONST - && EXPECTED(zend_execute_ex == execute_ex)) { - if (RETURN_VALUE_USED(opline)) { - const zend_op *op = new_op_array->opcodes; - ZVAL_COPY(EX_VAR(opline->result.var), RT_CONSTANT(op, op->op1)); - } - zend_destroy_static_vars(new_op_array); - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); - } else { - zval *return_value = NULL; - zend_execute_data *call; - if (RETURN_VALUE_USED(opline)) { - return_value = EX_VAR(opline->result.var); - } - new_op_array->scope = EX(func)->op_array.scope; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - call = zend_vm_stack_push_call_frame( - (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, - (zend_function*)new_op_array, 0, - Z_PTR(EX(This))); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ +#if 0 + USE_OPLINE +#endif - if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { - call->symbol_table = EX(symbol_table); - } else { - call->symbol_table = zend_rebuild_symbol_table(); + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - - call->prev_execute_data = execute_data; - i_init_code_execute_data(call, new_op_array, return_value); - - - if (EXPECTED(zend_execute_ex == execute_ex)) { - - - ZEND_VM_ENTER(); - } else { - ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); - zend_execute_ex(call); - zend_vm_stack_free_call_frame(call); + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if (IS_CONST == IS_UNUSED) { + ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - - zend_destroy_static_vars(new_op_array); - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - - - UNDEF_RESULT(); - HANDLE_EXCEPTION(); + if (IS_CV & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - - - ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_R_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *array_ptr, *result; + zval *container; SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + zend_fetch_dimension_address_UNSET(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); - array_ptr = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { - result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, array_ptr); - if (IS_CV != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(array_ptr); - } - Z_FE_POS_P(result) = 0; + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - ZEND_VM_NEXT_OPCODE(); - } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { - zend_object *zobj = Z_OBJ_P(array_ptr); - if (!zobj->ce->get_iterator) { - if (UNEXPECTED(zend_object_is_lazy(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (UNEXPECTED(EG(exception))) { - UNDEF_RESULT(); +static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + void **cache_slot = NULL; + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + if (IS_CV & (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); + } - HANDLE_EXCEPTION(); - } - } - HashTable *properties = zobj->properties; - if (properties) { - if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(properties); - } - properties = zobj->properties = zend_array_dup(properties); + if (IS_CV == IS_CONST || + (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if ((IS_CV & IS_CV) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; } - } else { - properties = zobj->handlers->get_properties(zobj); - } - - result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, array_ptr); - if (IS_CV != IS_TMP_VAR) { - Z_ADDREF_P(array_ptr); } - - if (zend_hash_num_elements(properties) == 0) { - Z_FE_ITER_P(result) = (uint32_t) -1; - - - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } + zend_wrong_property_read(container, RT_CONSTANT(opline, opline->op2)); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; + } while (0); + } - Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; + if (IS_CONST == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } else if (is_empty) { - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } - } else { - zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_r_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { +fetch_obj_r_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + prop_offset = prop_info->offset; + goto fetch_obj_r_simple; + } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { + zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; + ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); + ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); - } -} + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (IS_CV & IS_CV) { + GC_ADDREF(zobj); + } + if (IS_CV & (IS_CV|IS_VAR|IS_TMP_VAR)) { + call_info |= ZEND_CALL_RELEASE_THIS; + } + zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); + call->prev_execute_data = execute_data; + call->call = NULL; + call->return_value = EX_VAR(opline->result.var); + call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FE_RESET_RW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *array_ptr, *array_ref; + execute_data = call; + EG(current_execute_data) = execute_data; + zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); - SAVE_OPLINE(); +#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) + opline = hook->op_array.opcodes; +#else + EX(opline) = hook->op_array.opcodes; +#endif + LOAD_OPLINE_EX(); - if (IS_CV == IS_VAR || IS_CV == IS_CV) { - array_ref = array_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(array_ref)) { - array_ptr = Z_REFVAL_P(array_ref); - } - } else { - array_ref = array_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - } - if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { - if (IS_CV == IS_VAR || IS_CV == IS_CV) { - if (array_ptr == array_ref) { - ZVAL_NEW_REF(array_ref, array_ref); - array_ptr = Z_REFVAL_P(array_ref); - } - Z_ADDREF_P(array_ref); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); - } else { - array_ref = EX_VAR(opline->result.var); - ZVAL_NEW_REF(array_ref, array_ptr); - array_ptr = Z_REFVAL_P(array_ref); - } - if (IS_CV == IS_CONST) { - ZVAL_ARR(array_ptr, zend_array_dup(Z_ARRVAL_P(array_ptr))); - } else { - SEPARATE_ARRAY(array_ptr); - } - Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0); - ZEND_VM_NEXT_OPCODE(); - } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { - if (!Z_OBJCE_P(array_ptr)->get_iterator) { - zend_object *zobj = Z_OBJ_P(array_ptr); - HashTable *properties; - if (UNEXPECTED(zend_object_is_lazy(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (UNEXPECTED(EG(exception))) { - UNDEF_RESULT(); + ZEND_VM_ENTER_EX(); + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); - HANDLE_EXCEPTION(); - } - } - if (IS_CV == IS_VAR || IS_CV == IS_CV) { - if (array_ptr == array_ref) { - ZVAL_NEW_REF(array_ref, array_ref); - array_ptr = Z_REFVAL_P(array_ref); + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } } - Z_ADDREF_P(array_ref); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); - } else { - array_ptr = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(array_ptr, array_ref); } - if (Z_OBJ_P(array_ptr)->properties - && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(Z_OBJ_P(array_ptr)->properties); - } - Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + } else { + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; } + } - properties = Z_OBJPROP_P(array_ptr); - if (zend_hash_num_elements(properties) == 0) { - Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1; - +#if ZEND_DEBUG + /* For non-standard object handlers, verify a declared property type in debug builds. + * Fetch prop_info before calling read_property(), as it may deallocate the object. */ + zend_property_info *prop_info = NULL; + if (zobj->handlers->read_property != zend_std_read_property) { + prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); + } +#endif + retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO + && ZEND_TYPE_IS_SET(prop_info->type)) { + ZVAL_OPT_DEREF(retval); + zend_verify_property_type(prop_info, retval, /* strict */ true); + } +#endif - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); - } + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } - Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0); + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_r_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } + } while (0); +fetch_obj_r_finish: - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } else if (is_empty) { - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } - } else { - zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - zend_reference *ref = NULL; - bool ret; + zval *property, *container, *result; SAVE_OPLINE(); - value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - - if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(value)) { - if (IS_CV == IS_VAR) { - ref = Z_REF_P(value); - } - value = Z_REFVAL_P(value); - } - - ret = i_zend_is_true(value); - - if (UNEXPECTED(EG(exception))) { + container = EX_VAR(opline->op1.var); + property = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + zend_fetch_property_address( + result, container, IS_CV, property, IS_CONST, + ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - - if (ret) { - zval *result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, value); - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_CV == IS_CV) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); - } else if (IS_CV == IS_VAR && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } - - - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COALESCE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - zend_reference *ref = NULL; + zval *property, *container, *result; SAVE_OPLINE(); - value = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); - - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - if (IS_CV & IS_VAR) { - ref = Z_REF_P(value); - } - value = Z_REFVAL_P(value); - } + container = EX_VAR(opline->op1.var); + property = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - if (Z_TYPE_P(value) > IS_NULL) { - zval *result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, value); - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_CV == IS_CV) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); - } else if ((IS_CV & IS_VAR) && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - if ((IS_CV & IS_VAR) && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_JMP_NULL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val, *result; + zval *container; + void **cache_slot = NULL; - val = EX_VAR(opline->op1.var); + SAVE_OPLINE(); + container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ - if (Z_TYPE_P(val) > IS_NULL) { + if (IS_CV == IS_CONST || + (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { do { - if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { - val = Z_REFVAL_P(val); - if (Z_TYPE_P(val) <= IS_NULL) { - - + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; } } - ZEND_VM_NEXT_OPCODE(); + if (IS_CONST == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + } + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; } while (0); } - result = EX_VAR(opline->result.var); - uint32_t short_circuiting_type = opline->extended_value & ZEND_SHORT_CIRCUITING_CHAIN_MASK; - if (EXPECTED(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { - ZVAL_NULL(result); - if (IS_CV == IS_CV - && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF) - && (opline->extended_value & ZEND_JMP_NULL_BP_VAR_IS) == 0 - ) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - } else if (short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { - ZVAL_FALSE(result); - } else { - ZEND_ASSERT(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); - ZVAL_TRUE(result); - } + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); -} + if (IS_CONST == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value); -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *result = EX_VAR(opline->result.var); + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - value = EX_VAR(opline->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_is_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { +fetch_obj_is_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + goto fetch_obj_is_simple; + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); - if (IS_CV == IS_CV) { - ZVAL_COPY_DEREF(result, value); - } else if (IS_CV == IS_VAR) { - if (UNEXPECTED(Z_ISREF_P(value))) { - ZVAL_COPY_VALUE(result, Z_REFVAL_P(value)); - if (UNEXPECTED(Z_DELREF_P(value) == 0)) { - efree_size(Z_REF_P(value), sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } + } + } } + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); } else { - ZVAL_COPY_VALUE(result, value); - } - } else { - ZVAL_COPY_VALUE(result, value); - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) { - Z_ADDREF_P(result); + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; } } - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_FROM_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - zval *val; - - SAVE_OPLINE(); - val = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator"); - - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } + retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); -yield_from_try_again: - if (Z_TYPE_P(val) == IS_ARRAY) { - ZVAL_COPY_VALUE(&generator->values, val); - if (Z_OPT_REFCOUNTED_P(val)) { - Z_ADDREF_P(val); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } - Z_FE_POS(generator->values) = 0; + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_is_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } + } while (0); - } else if (IS_CV != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) { - zend_class_entry *ce = Z_OBJCE_P(val); - if (ce == zend_ce_generator) { - zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); +fetch_obj_is_finish: - Z_ADDREF_P(val); - if (UNEXPECTED(new_gen->execute_data == NULL)) { - zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); - zval_ptr_dtor(val); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else if (Z_ISUNDEF(new_gen->retval)) { - if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) { - zend_throw_error(NULL, "Impossible to yield from the Generator being currently run"); - zval_ptr_dtor(val); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else { - zend_generator_yield_from(generator, new_gen); - } - } else { - if (RETURN_VALUE_USED(opline)) { - ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval); - } - ZEND_VM_NEXT_OPCODE(); - } - } else { - zend_object_iterator *iter = ce->get_iterator(ce, val, 0); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) { - if (!EG(exception)) { - zend_throw_error(NULL, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name)); - } - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ +#if 0 + USE_OPLINE +#endif - iter->index = 0; - if (iter->funcs->rewind) { - iter->funcs->rewind(iter); - if (UNEXPECTED(EG(exception) != NULL)) { - OBJ_RELEASE(&iter->std); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + /* Behave like FETCH_OBJ_W */ + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if (IS_CV == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); } } - - ZVAL_OBJ(&generator->values, &iter->std); } - } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(val) == IS_REFERENCE) { - val = Z_REFVAL_P(val); - goto yield_from_try_again; - } else { - zend_throw_error(NULL, "Can use \"yield from\" only with arrays and Traversables"); - - - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - - /* This is the default return value - * when the expression is a Generator, it will be overwritten in zend_generator_resume() */ - if (RETURN_VALUE_USED(opline)) { - ZVAL_NULL(EX_VAR(opline->result.var)); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } +} - /* This generator has no send target (though the generator we delegate to might have one) */ - generator->send_target = NULL; +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container, *property, *result; - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + property = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - ZEND_VM_RETURN(); + + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_STRLEN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - - value = EX_VAR(opline->op1.var); - if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(value); - } - ZEND_VM_NEXT_OPCODE(); - } else { - bool strict; - - if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) { - value = Z_REFVAL_P(value); - if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; + SAVE_OPLINE(); + object = EX_VAR(opline->op1.var); + value = RT_CONSTANT((opline+1), (opline+1)->op1); - ZEND_VM_NEXT_OPCODE(); - } + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; } + zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } - SAVE_OPLINE(); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - value = ZVAL_UNDEFINED_OP1(); - } - strict = EX_USES_STRICT_TYPES(); - do { - if (EXPECTED(!strict)) { - zend_string *str; - zval tmp; +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) { - zend_error(E_DEPRECATED, - "strlen(): Passing null to parameter #1 ($string) of type string is deprecated"); - ZVAL_LONG(EX_VAR(opline->result.var), 0); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; } - break; } - ZVAL_COPY(&tmp, value); - if (zend_parse_arg_str_weak(&tmp, &str, 1)) { - ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str)); - zval_ptr_dtor(&tmp); - break; + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CONST != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CONST == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CONST == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; } - zval_ptr_dtor(&tmp); - } - if (!EG(exception)) { - zend_type_error("strlen(): Argument #1 ($string) must be of type string, %s given", zend_zval_value_name(value)); + } else { + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ } - ZVAL_UNDEF(EX_VAR(opline->result.var)); - } while (0); - } - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + } + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + } else { + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + if (UNEXPECTED(!name)) { -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_TYPE_CHECK_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - int result = 0; - value = EX_VAR(opline->op1.var); - if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { -type_check_resource: - if (opline->extended_value != MAY_BE_RESOURCE - || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) { - result = 1; - } - } else if ((IS_CV & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) { - value = Z_REFVAL_P(value); - if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { - goto type_check_resource; - } - } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - result = ((1 << IS_NULL) & opline->extended_value) != 0; - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); + UNDEF_RESULT(); + goto exit_assign_obj; } } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - SAVE_OPLINE(); - - ZEND_VM_SMART_BRANCH(result, 1); - } else { - ZEND_VM_SMART_BRANCH(result, 0); + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_DEREF(value); } -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_CLASS_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - uint32_t fetch_type; - zend_class_entry *called_scope, *scope; - USE_OPLINE + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if (IS_CV != IS_UNUSED) { - SAVE_OPLINE(); - zval *op = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(Z_TYPE_P(op) != IS_OBJECT)) { - ZVAL_DEREF(op); - if (Z_TYPE_P(op) != IS_OBJECT) { - zend_type_error("Cannot use \"::class\" on %s", zend_zval_value_name(op)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } - HANDLE_EXCEPTION(); - } - } - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op)->name); +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - fetch_type = opline->op1.num; - scope = EX(func)->op_array.scope; - if (UNEXPECTED(scope == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", - fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : - fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - switch (fetch_type) { - case ZEND_FETCH_CLASS_SELF: - ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->name); - break; - case ZEND_FETCH_CLASS_PARENT: - if (UNEXPECTED(scope->parent == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, - "Cannot use \"parent\" when current class scope has no parent"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->parent->name); - break; - case ZEND_FETCH_CLASS_STATIC: - if (Z_TYPE(EX(This)) == IS_OBJECT) { - called_scope = Z_OBJCE(EX(This)); - } else { - called_scope = Z_CE(EX(This)); - } - ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } - ZEND_VM_NEXT_OPCODE(); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BIND_STATIC_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - HashTable *ht; - zval *value; - zval *variable_ptr; - - variable_ptr = EX_VAR(opline->op1.var); + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); + object = EX_VAR(opline->op1.var); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr); - if (!ht) { - ht = zend_array_dup(EX(func)->op_array.static_variables); - ZEND_MAP_PTR_SET(EX(func)->op_array.static_variables_ptr, ht); - } - ZEND_ASSERT(GC_REFCOUNT(ht) == 1); - - value = (zval*)((char*)ht->arData + (opline->extended_value & ~(ZEND_BIND_REF|ZEND_BIND_IMPLICIT|ZEND_BIND_EXPLICIT))); - - if (opline->extended_value & ZEND_BIND_REF) { - if (UNEXPECTED(!Z_ISREF_P(value))) { - zend_reference *ref = (zend_reference*)emalloc(sizeof(zend_reference)); - GC_SET_REFCOUNT(ref, 2); - GC_TYPE_INFO(ref) = GC_REFERENCE; - if (opline->op2_type == IS_UNUSED) { - ZVAL_COPY_VALUE(&ref->val, value); - } else { - ZEND_ASSERT(!Z_REFCOUNTED_P(value)); - ZVAL_COPY(&ref->val, get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R)); - FREE_OP(opline->op2_type, opline->op2.var); - } - ref->sources.ptr = NULL; - Z_REF_P(value) = ref; - Z_TYPE_INFO_P(value) = IS_REFERENCE_EX; - i_zval_ptr_dtor(variable_ptr); - ZVAL_REF(variable_ptr, ref); - } else { - Z_ADDREF_P(value); - i_zval_ptr_dtor(variable_ptr); - ZVAL_REF(variable_ptr, Z_REF_P(value)); - if (opline->op2_type != IS_UNUSED) { - FREE_OP(opline->op2_type, opline->op2.var); - } + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; } - } else { - i_zval_ptr_dtor(variable_ptr); - ZVAL_COPY(variable_ptr, value); + zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BIND_INIT_STATIC_OR_JMP_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - HashTable *ht; - zval *value; - zval *variable_ptr; +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - variable_ptr = EX_VAR(opline->op1.var); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr); - if (!ht) { - ZEND_VM_NEXT_OPCODE(); - } - ZEND_ASSERT(GC_REFCOUNT(ht) == 1); +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } - value = (zval*)((char*)ht->arData + opline->extended_value); - if (Z_TYPE_P(value) == IS_NULL) { - ZEND_VM_NEXT_OPCODE(); + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_TMP_VAR == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_TMP_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ + } + } + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); } else { - SAVE_OPLINE(); - zval_ptr_dtor(variable_ptr); - ZEND_ASSERT(Z_TYPE_P(value) == IS_REFERENCE); - Z_ADDREF_P(value); - ZVAL_REF(variable_ptr, Z_REF_P(value)); - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 1); + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + if (UNEXPECTED(!name)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + goto exit_assign_obj; + } } -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - var_ptr = EX_VAR(opline->op1.var); - Z_LVAL_P(var_ptr)++; - if (UNEXPECTED(0)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_DEREF(value); } - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - var_ptr = EX_VAR(opline->op1.var); - Z_LVAL_P(var_ptr)++; - if (UNEXPECTED(1)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - fast_long_increment_function(var_ptr); - if (UNEXPECTED(0)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - fast_long_increment_function(var_ptr); - if (UNEXPECTED(1)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); } - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - var_ptr = EX_VAR(opline->op1.var); - Z_LVAL_P(var_ptr)--; - if (UNEXPECTED(0)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - } - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - var_ptr = EX_VAR(opline->op1.var); - Z_LVAL_P(var_ptr)--; - if (UNEXPECTED(1)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - } - ZEND_VM_NEXT_OPCODE(); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - fast_long_decrement_function(var_ptr); - if (UNEXPECTED(0)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); - } - ZEND_VM_NEXT_OPCODE(); -} + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; + SAVE_OPLINE(); + object = EX_VAR(opline->op1.var); + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - var_ptr = EX_VAR(opline->op1.var); - fast_long_decrement_function(var_ptr); - if (UNEXPECTED(1)) { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr); + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; + } + zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - - var_ptr = EX_VAR(opline->op1.var); - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - Z_LVAL_P(var_ptr)++; - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_LONG_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CONST == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - var_ptr = EX_VAR(opline->op1.var); - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - fast_long_increment_function(var_ptr); - ZEND_VM_NEXT_OPCODE(); -} + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } - var_ptr = EX_VAR(opline->op1.var); - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - Z_LVAL_P(var_ptr)--; - ZEND_VM_NEXT_OPCODE(); -} + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CV != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CV == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CV == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ + } + } + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + } else { + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + if (UNEXPECTED(!name)) { -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_DEC_LONG_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - var_ptr = EX_VAR(opline->op1.var); - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr)); - fast_long_decrement_function(var_ptr); - ZEND_VM_NEXT_OPCODE(); -} + UNDEF_RESULT(); + goto exit_assign_obj; + } + } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SIMPLE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr, *arg; + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_DEREF(value); + } - varptr = EX_VAR(opline->op1.var); - arg = ZEND_CALL_VAR(EX(call), opline->result.var); + value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if (IS_CV == IS_CV) { - ZVAL_COPY(arg, varptr); - } else /* if (IS_CV == IS_VAR) */ { - ZVAL_COPY_VALUE(arg, varptr); + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); } - ZEND_VM_NEXT_OPCODE(); -} +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - div_function(EX_VAR(opline->result.var), op1, op2); +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - pow_function(EX_VAR(opline->result.var), op1, op2); - - - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - - if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_CONST == IS_UNUSED) { + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; + } } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if (IS_CV == IS_CONST || IS_CV == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else if (IS_CV != IS_CONST && IS_CV != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { - zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_DEREF(value); } - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_CONST == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } else if (IS_CONST == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } } } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); + dim = RT_CONSTANT(opline, opline->op2); + if (IS_CONST == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; } + value = RT_CONSTANT((opline+1), (opline+1)->op1); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); } - ZEND_VM_NEXT_OPCODE(); - } else { - SAVE_OPLINE(); - - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = ZVAL_UNDEFINED_OP2(); + if (garbage) { + GC_DTOR_NO_REF(garbage); } - concat_function(EX_VAR(opline->result.var), op1, op2); + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + GC_ADDREF(obj); + dim = RT_CONSTANT(opline, opline->op2); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_CONST & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_CONST == IS_UNUSED) { + zend_use_new_element_for_string(); - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_identical_function(op1, op2); + UNDEF_RESULT(); + } else { + dim = RT_CONSTANT(opline, opline->op2); + value = RT_CONSTANT((opline+1), (opline+1)->op1); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = RT_CONSTANT(opline, opline->op2); - ZEND_VM_SMART_BRANCH(result, 1); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + UNDEF_RESULT(); + } else { + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_not_identical_function(op1, op2); + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + goto try_assign_dim_array; + } + } else { + zend_use_scalar_as_array(); + dim = RT_CONSTANT(opline, opline->op2); +assign_dim_error: + + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + if (IS_CONST != IS_UNUSED) { + } - ZEND_VM_SMART_BRANCH(result, 1); + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; + SAVE_OPLINE(); + orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_CONST == IS_UNUSED) { + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; + } } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_DEREF(value); } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_TMP_VAR == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } else if (IS_TMP_VAR == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } } - if (result) { - goto is_equal_true; + } else { + dim = RT_CONSTANT(opline, opline->op2); + if (IS_CONST == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { - goto is_equal_false; + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); + dim = RT_CONSTANT(opline, opline->op2); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; + + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_CONST == IS_UNUSED) { + zend_use_new_element_for_string(); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); + dim = RT_CONSTANT(opline, opline->op2); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } - if (result) { - goto is_equal_true; + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = RT_CONSTANT(opline, opline->op2); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); } else { - goto is_equal_false; + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + goto try_assign_dim_array; + } + } else { + zend_use_scalar_as_array(); + dim = RT_CONSTANT(opline, opline->op2); +assign_dim_error: + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); } } } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} + if (IS_CONST != IS_UNUSED) { -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + + + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + SAVE_OPLINE(); + orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_CONST == IS_UNUSED) { + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_DEREF(value); + } + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_CV == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } else if (IS_CV == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } + } else { + dim = RT_CONSTANT(opline, opline->op2); + if (IS_CONST == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); + dim = RT_CONSTANT(opline, opline->op2); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); + + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_CV & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; + + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + + + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_CONST == IS_UNUSED) { + zend_use_new_element_for_string(); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CV == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + UNDEF_RESULT(); } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + dim = RT_CONSTANT(opline, opline->op2); + value = EX_VAR((opline+1)->op1.var); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + + } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = RT_CONSTANT(opline, opline->op2); + + + UNDEF_RESULT(); } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + goto try_assign_dim_array; } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; + } else { + zend_use_scalar_as_array(); + dim = RT_CONSTANT(opline, opline->op2); +assign_dim_error: + + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); } } } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + if (IS_CONST != IS_UNUSED) { + + + } + + + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *value; + zval *variable_ptr; SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - compare_function(EX_VAR(opline->result.var), op1, op2); + value = RT_CONSTANT(opline, opline->op2); + variable_ptr = EX_VAR(opline->op1.var); + + if (0 || UNEXPECTED(0)) { + zend_refcounted *garbage = NULL; + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES()); + } + /* zend_assign_to_variable() always takes care of op2, never free it! */ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_XOR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *value; + zval *variable_ptr; SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - boolean_xor_function(EX_VAR(opline->result.var), op1, op2); + value = RT_CONSTANT(opline, opline->op2); + variable_ptr = EX_VAR(opline->op1.var); + + if (0 || UNEXPECTED(1)) { + zend_refcounted *garbage = NULL; + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(1)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES()); + } + /* zend_assign_to_variable() always takes care of op2, never free it! */ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object; - zval *property; - zval *value; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; + zval *property, *container, *value_ptr; SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); + + container = EX_VAR(opline->op1.var); property = RT_CONSTANT(opline, opline->op2); - do { - value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); + value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_op_object; - } - if (IS_CV == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (1) { + if (IS_CV == IS_UNUSED) { + if (IS_CONST == IS_CONST) { + zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; - } - -assign_op_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - name = Z_STR_P(property); } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - UNDEF_RESULT(); - break; - } - } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } + if (IS_CONST == IS_CONST) { + zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { - zend_reference *ref; - - do { - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - zptr = Z_REFVAL_P(zptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - if (prop_info) { - /* special case for typed properties */ - zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_binary_op(zptr, zptr, value OPLINE_CC); - } - } while (0); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), zptr); - } + zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } - } else { - zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); - } - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); } - } while (0); - - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + } else { + zend_assign_to_property_reference(container, IS_CV, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } - /* assign_obj has two opcodes! */ + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; - zval *value, *container, *dim; - HashTable *ht; + zval *property, *container, *value_ptr; SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + property = RT_CONSTANT(opline, opline->op2); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -assign_dim_op_array: - SEPARATE_ARRAY(container); - ht = Z_ARRVAL_P(container); -assign_dim_op_new_array: - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); - if (UNEXPECTED(!var_ptr)) { - zend_cannot_add_element(); - goto assign_dim_op_ret_null; + value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); + + if (1) { + if (IS_CV == IS_UNUSED) { + if (IS_CONST == IS_CONST) { + zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } else { if (IS_CONST == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); + zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { - var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(!var_ptr)) { - goto assign_dim_op_ret_null; - } - } - - value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - - do { - if (IS_CONST != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } + zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } - zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); - } while (0); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); } else { - if (EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto assign_dim_op_array; - } - } - - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(container); + zend_assign_to_property_reference(container, IS_CV, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); - } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - uint8_t old_type; - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - ht = zend_new_array(8); - old_type = Z_TYPE_P(container); - ZVAL_ARR(container, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_op_ret_null; - } - } - goto assign_dim_op_new_array; - } else { - dim = RT_CONSTANT(opline, opline->op2); - zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); -assign_dim_op_ret_null: - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } @@ -43767,95 +43708,125 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; - zval *value; - - SAVE_OPLINE(); - value = RT_CONSTANT(opline, opline->op2); - var_ptr = _get_zval_ptr_cv_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC); - - do { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); - } while (0); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - } + zval *op1, *op2; + zend_string *op1_str, *op2_str, *str; + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else if (IS_CV != IS_CONST && IS_CV != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; - - SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - property = RT_CONSTANT(opline, opline->op2); - - do { - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto pre_incdec_object; + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); } - if (IS_CV == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; } + ZEND_VM_NEXT_OPCODE(); + } -pre_incdec_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - UNDEF_RESULT(); + SAVE_OPLINE(); + if (IS_CV == IS_CONST) { + op1_str = Z_STR_P(op1); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + op1_str = zend_string_copy(Z_STR_P(op1)); + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + op1_str = zval_get_string_func(op1); + } + if (IS_CONST == IS_CONST) { + op2_str = Z_STR_P(op2); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + op2_str = zend_string_copy(Z_STR_P(op2)); + } else { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + } + op2_str = zval_get_string_func(op2); + } + do { + if (IS_CV != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + zend_string_release_ex(op1_str, 0); break; } } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); + if (IS_CONST != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } } - } else { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + zend_string_release_ex(op2_str, 0); + break; } - } else { - zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); + } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + + ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CV != IS_CONST) { + zend_string_release_ex(op1_str, 0); } if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); + zend_string_release_ex(op2_str, 0); } } while (0); @@ -43865,10939 +43836,4947 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_S ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *function_name; zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; + zend_function *fbc; + zend_class_entry *called_scope; + zend_object *obj; + zend_execute_data *call; + uint32_t call_info; SAVE_OPLINE(); + object = EX_VAR(opline->op1.var); - property = RT_CONSTANT(opline, opline->op2); - do { - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto post_incdec_object; - } - if (IS_CV == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; - } + if (IS_CONST != IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } -post_incdec_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; + if (IS_CONST != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + + + HANDLE_EXCEPTION(); + } } - } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - ZVAL_NULL(EX_VAR(opline->result.var)); + zend_throw_error(NULL, "Method name must be a string"); + + + + + HANDLE_EXCEPTION(); + } while (0); + } + + if (IS_CV == IS_UNUSED) { + obj = Z_OBJ_P(object); + } else { + do { + if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); } else { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); + if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + if (IS_CV & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } + break; + } + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + object = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_CONST != IS_CONST) { + + + } + HANDLE_EXCEPTION(); + } + } + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } + zend_invalid_method_call(object, function_name); + + + + + HANDLE_EXCEPTION(); } - } else { - zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); - } - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - } while (0); + } while (0); + } + called_scope = obj->ce; + if (IS_CONST == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else { + zend_object *orig_obj = obj; + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + /* First, locate the function. */ + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container, *dim, *value; - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CV != IS_CONST) { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R EXECUTE_DATA_CC); - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_array; - } else { - goto fetch_dim_r_slow; + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); } - } else { -fetch_dim_r_slow: - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; + HANDLE_EXCEPTION(); + } + if (IS_CONST == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(obj == orig_obj)) { + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); + } + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); } - zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); } - } else { - zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } } + if (IS_CONST != IS_CONST) { + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; + } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { + if (IS_CV == IS_CV) { + GC_ADDREF(obj); /* For $this pointer */ + } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; + } + + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, obj); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; + zval *varptr, *arg; - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_W(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); + if (IS_CONST == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + uint32_t arg_num; + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + HANDLE_EXCEPTION(); + } + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_RW(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); + varptr = EX_VAR(opline->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(arg); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + if (IS_CV == IS_CV) { + ZVAL_COPY_DEREF(arg, varptr); + } else /* if (IS_CV == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(varptr))) { + zend_refcounted *ref = Z_COUNTED_P(varptr); - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + varptr = Z_REFVAL_P(varptr); + ZVAL_COPY_VALUE(arg, varptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(arg)) { + Z_ADDREF_P(arg); + } + } else { + ZVAL_COPY_VALUE(arg, varptr); + } } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_REF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; + zval *varptr, *arg; SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_read_IS(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); + if (IS_CONST == IS_CONST) { + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + uint32_t arg_num; + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + + HANDLE_EXCEPTION(); + } + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + } + varptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(varptr)) { + Z_ADDREF_P(varptr); + } else { + ZVAL_MAKE_REF_EX(varptr, 2); + } + ZVAL_REF(arg, Z_REF_P(varptr)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if 0 USE_OPLINE -#endif + zval *varptr, *arg; + uint32_t arg_num; - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_CONST == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + + + HANDLE_EXCEPTION(); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - if (IS_CONST == IS_UNUSED) { - ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + arg_num = opline->op2.num; } -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; + if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) { + if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_var_by_ref; + } + } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { +send_var_by_ref: + varptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(varptr)) { + Z_ADDREF_P(varptr); + } else { + ZVAL_MAKE_REF_EX(varptr, 2); + } + ZVAL_REF(arg, Z_REF_P(varptr)); - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_UNSET(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); + ZEND_VM_NEXT_OPCODE(); + } - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + varptr = EX_VAR(opline->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(arg); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + if (IS_CV == IS_CV) { + ZVAL_COPY_DEREF(arg, varptr); + } else /* if (IS_CV == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(varptr))) { + zend_refcounted *ref = Z_COUNTED_P(varptr); + + varptr = Z_REFVAL_P(varptr); + ZVAL_COPY_VALUE(arg, varptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(arg)) { + Z_ADDREF_P(arg); + } + } else { + ZVAL_COPY_VALUE(arg, varptr); + } + } + + ZEND_VM_NEXT_OPCODE(); } -static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - void **cache_slot = NULL; + zval *expr_ptr, new_expr; SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - - if (IS_CV == IS_CONST || - (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - break; - } - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_wrong_property_read(container, RT_CONSTANT(opline, opline->op2)); - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_r_finish; - } while (0); - } - - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; - - if (IS_CONST == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); - - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_r_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { -fetch_obj_r_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - prop_offset = prop_info->offset; - goto fetch_obj_r_simple; - } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { - zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; - ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); - ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); - - uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (IS_CV & IS_CV) { - GC_ADDREF(zobj); - } - if (IS_CV & (IS_CV|IS_VAR|IS_TMP_VAR)) { - call_info |= ZEND_CALL_RELEASE_THIS; - } - zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); - call->prev_execute_data = execute_data; - call->call = NULL; - call->return_value = EX_VAR(opline->result.var); - call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); - - execute_data = call; - EG(current_execute_data) = execute_data; - zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); - -#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) - opline = hook->op_array.opcodes; -#else - EX(opline) = hook->op_array.opcodes; -#endif - LOAD_OPLINE_EX(); - + if ((IS_CV == IS_VAR || IS_CV == IS_CV) && + UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { + expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } else { + ZVAL_MAKE_REF_EX(expr_ptr, 2); + } + } else { + expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + if (IS_CV == IS_TMP_VAR) { + /* pass */ + } else if (IS_CV == IS_CONST) { + Z_TRY_ADDREF_P(expr_ptr); + } else if (IS_CV == IS_CV) { + ZVAL_DEREF(expr_ptr); + Z_TRY_ADDREF_P(expr_ptr); + } else /* if (IS_CV == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(expr_ptr); - ZEND_VM_ENTER_EX(); - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + expr_ptr = Z_REFVAL_P(expr_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + ZVAL_COPY_VALUE(&new_expr, expr_ptr); + expr_ptr = &new_expr; + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } + } + } + } - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + if (IS_CONST != IS_UNUSED) { + zval *offset = RT_CONSTANT(opline, opline->op2); + zend_string *str; + zend_ulong hval; - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; - } - } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; - } - } +add_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_CONST != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index; } } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; +str_index: + zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index: + zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto add_again; + } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { + zval tmp; + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_COPY(&tmp, expr_ptr); } + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + /* A userland error handler can do funky things to the expression, so reset it */ + zval_ptr_dtor(expr_ptr); + ZVAL_COPY_VALUE(expr_ptr, &tmp); + } + if (UNEXPECTED(EG(exception))) { + zval_ptr_dtor_nogc(expr_ptr); + HANDLE_EXCEPTION(); + } + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + goto num_index; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); + hval = Z_RES_HANDLE_P(offset); + goto num_index; + } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else { + zend_illegal_array_offset_access(offset); + zval_ptr_dtor_nogc(expr_ptr); } -#if ZEND_DEBUG - /* For non-standard object handlers, verify a declared property type in debug builds. - * Fetch prop_info before calling read_property(), as it may deallocate the object. */ - zend_property_info *prop_info = NULL; - if (zobj->handlers->read_property != zend_std_read_property) { - prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); - } -#endif - retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); -#if ZEND_DEBUG - if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { - ZVAL_OPT_DEREF(retval); - zend_verify_property_type(prop_info, retval, /* strict */ true); - } -#endif - - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_r_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); + } else { + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(expr_ptr); } - } while (0); - -fetch_obj_r_finish: - - - - + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CONST_INLINE_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zval *array; + uint32_t size; USE_OPLINE - zval *property, *container, *result; SAVE_OPLINE(); - - container = EX_VAR(opline->op1.var); - property = RT_CONSTANT(opline, opline->op2); - result = EX_VAR(opline->result.var); - zend_fetch_property_address( - result, container, IS_CV, property, IS_CONST, - ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); - - - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + array = EX_VAR(opline->result.var); + if (IS_CV != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_ARR(array, zend_new_array(0)); + ZEND_VM_NEXT_OPCODE(); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *property, *container, *result; + zval *container; + zval *offset; + zend_ulong hval; + zend_string *key; SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - property = RT_CONSTANT(opline, opline->op2); - result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + offset = RT_CONSTANT(opline, opline->op2); + + do { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + +unset_dim_array: + SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); +offset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + key = Z_STR_P(offset); + if (IS_CONST != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(key, hval)) { + goto num_index_dim; + } + } +str_index_dim: + ZEND_ASSERT(ht != &EG(symbol_table)); + zend_hash_del(ht, key); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_dim: + zend_hash_index_del(ht, hval); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto offset_again; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + /* The array may be destroyed while throwing a warning in case the float is not representable as an int. + * Temporarily increase the refcount to detect this situation. */ + GC_TRY_ADDREF(ht); + hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + break; + } + if (EG(exception)) { + break; + } + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_NULL) { + key = ZSTR_EMPTY_ALLOC(); + goto str_index_dim; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + key = ZSTR_EMPTY_ALLOC(); + goto str_index_dim; + } else { + zend_illegal_array_offset_unset(offset); + } + break; + } else if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto unset_dim_array; + } + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + container = ZVAL_UNDEFINED_OP1(); + } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + offset = ZVAL_UNDEFINED_OP2(); + } + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; + } + Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset); + } else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { + zend_throw_error(NULL, "Cannot unset string offsets"); + } else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) { + zend_throw_error(NULL, "Cannot unset offset in a non-array variable"); + } else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) { + zend_false_to_array_deprecated(); + } + } while (0); + + - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; - void **cache_slot = NULL; + zval *offset; + zend_string *name, *tmp_name; SAVE_OPLINE(); - container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); + container = EX_VAR(opline->op1.var); + offset = RT_CONSTANT(opline, opline->op2); - if (IS_CV == IS_CONST || - (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + do { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + if (Z_TYPE_P(container) != IS_OBJECT) { + if (IS_CV == IS_CV + && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } break; } + } else { + break; } - if (IS_CONST == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - } - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_is_finish; - } while (0); - } - - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; - + } if (IS_CONST == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value); - - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_is_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { -fetch_obj_is_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - goto fetch_obj_is_simple; - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); - - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); - - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } - } - } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + name = Z_STR_P(offset); } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + name = zval_try_get_tmp_string(offset, &tmp_name); if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); break; } } - - retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - + Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); } - - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_is_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } } while (0); -fetch_obj_is_finish: - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ -#if 0 - USE_OPLINE -#endif - - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - /* Behave like FETCH_OBJ_W */ - if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container, *property, *result; + zval *container; + bool result; + zend_ulong hval; + zval *offset; SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - property = RT_CONSTANT(opline, opline->op2); - result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - + offset = RT_CONSTANT(opline, opline->op2); - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + zval *value; + zend_string *str; -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - value = RT_CONSTANT((opline+1), (opline+1)->op1); - - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; +isset_dim_obj_array: + ht = Z_ARRVAL_P(container); +isset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_CONST != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_prop; + } + } + value = zend_hash_find_ex(ht, str, IS_CONST == IS_CONST); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_prop: + value = zend_hash_index_find(ht, hval); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + offset = Z_REFVAL_P(offset); + goto isset_again; + } else { + value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); + if (UNEXPECTED(EG(exception))) { + result = 0; + goto isset_dim_obj_exit; + } } - zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; + if (!(opline->extended_value & ZEND_ISEMPTY)) { + /* > IS_NULL means not IS_UNDEF and not IS_NULL */ + result = value != NULL && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + if (IS_CV & (IS_CONST|IS_CV)) { + /* avoid exception check */ -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CONST != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CONST == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_CONST == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ + ZEND_VM_SMART_BRANCH(result, 0); } + } else { + result = (value == NULL || !i_zend_is_true(value)); } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); - if (UNEXPECTED(!name)) { - - - UNDEF_RESULT(); - goto exit_assign_obj; + goto isset_dim_obj_exit; + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto isset_dim_obj_array; } } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); + if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + if (!(opline->extended_value & ZEND_ISEMPTY)) { + result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); + } else { + result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); } - -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } +isset_dim_obj_exit: - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; + zval *container; + int result; + zval *offset; zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); + offset = RT_CONSTANT(opline, opline->op2); - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; + if (IS_CV == IS_CONST || + (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } + } else { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } - zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; } -assign_object: - zobj = Z_OBJ_P(object); if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_TMP_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_TMP_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_TMP_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + name = Z_STR_P(offset); } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + name = zval_try_get_tmp_string(offset, &tmp_name); if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; + result = 0; + goto isset_object_finish; } } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); } -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } +isset_object_finish: - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; + + zval *key, *subject; + HashTable *ht; + bool result; SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; + key = EX_VAR(opline->op1.var); + subject = RT_CONSTANT(opline, opline->op2); + + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: + ht = Z_ARRVAL_P(subject); + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); + } else { + if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } } - zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; + zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); + result = 0; } -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *expr; + bool result; + + SAVE_OPLINE(); + expr = EX_VAR(opline->op1.var); + +try_instanceof: + if (Z_TYPE_P(expr) == IS_OBJECT) { + zend_class_entry *ce; + + if (IS_CONST == IS_CONST) { + ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (EXPECTED(ce)) { + CACHE_PTR(opline->extended_value, ce); } - /* Fall through to write_property for hooks. */ } + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { + expr = Z_REFVAL_P(expr); + goto try_instanceof; } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } + result = 0; } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + ZEND_VM_SMART_BRANCH(result, 1); +} - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + + SAVE_OPLINE(); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - - - - - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; + /* Set the new yielded value */ + if (IS_CV != IS_UNUSED) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_CV & (IS_CONST|IS_TMP_VAR)) { + zval *value; - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; + value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); } } + } else { + zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CV != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CV == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_CV == IS_CV) { - Z_TRY_ADDREF_P(value); + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + do { + if (IS_CV == IS_VAR) { + ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION + && !Z_ISREF_P(value_ptr)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + ZVAL_COPY(&generator->value, value_ptr); + break; } } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + if (Z_ISREF_P(value_ptr)) { + Z_ADDREF_P(value_ptr); + } else { + ZVAL_MAKE_REF_EX(value_ptr, 2); } - goto exit_assign_obj; + ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); + } while (0); + + + } + } else { + zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + + /* Consts, temporary variables and references need copying */ + if (IS_CV == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); } + } else if (IS_CV == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + + } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CV == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - /* Fall through to write_property for hooks. */ } } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); - if (UNEXPECTED(!name)) { - - - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_DEREF(value); + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); } - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + /* Set the new yielded key */ + if (IS_CONST != IS_UNUSED) { + zval *key = RT_CONSTANT(opline, opline->op2); + if ((IS_CONST & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + key = Z_REFVAL_P(key); + } + ZVAL_COPY(&generator->key, key); - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); + } + } else { + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); } - -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; } + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); - - - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_RETURN(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; + zend_string *varname; zval *value; zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; + uintptr_t idx; + zend_reference *ref; - SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); + ZEND_VM_REPEATABLE_OPCODE - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_CONST == IS_UNUSED) { - value = RT_CONSTANT((opline+1), (opline+1)->op1); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_CONST == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_CONST == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = RT_CONSTANT((opline+1), (opline+1)->op1); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); + varname = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + + /* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ + idx = (uintptr_t)CACHED_PTR(opline->extended_value) - 1; + if (EXPECTED(idx < EG(symbol_table).nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)EG(symbol_table).arData + idx); + + if (EXPECTED(p->key == varname) || + (EXPECTED(p->h == ZSTR_H(varname)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, varname)))) { + + value = (zval*)p; /* value = &p->val; */ + goto check_indirect; } + } + + value = zend_hash_find_known_hash(&EG(symbol_table), varname); + if (UNEXPECTED(value == NULL)) { + value = zend_hash_add_new(&EG(symbol_table), varname, &EG(uninitialized_zval)); + idx = (char*)value - (char*)EG(symbol_table).arData; + /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ + CACHE_PTR(opline->extended_value, (void*)(idx + 1)); } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; + idx = (char*)value - (char*)EG(symbol_table).arData; + /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ + CACHE_PTR(opline->extended_value, (void*)(idx + 1)); +check_indirect: + /* GLOBAL variable may be an INDIRECT pointer to CV */ + if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { + value = Z_INDIRECT_P(value); + if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + ZVAL_NULL(value); } } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); + } - GC_ADDREF(obj); - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } + if (UNEXPECTED(!Z_ISREF_P(value))) { + ZVAL_MAKE_REF_EX(value, 2); + ref = Z_REF_P(value); + } else { + ref = Z_REF_P(value); + GC_ADDREF(ref); + } - value = RT_CONSTANT((opline+1), (opline+1)->op1); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_CONST & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); + variable_ptr = EX_VAR(opline->op1.var); + + if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) { + zend_refcounted *garbage = Z_COUNTED_P(variable_ptr); + + ZVAL_REF(variable_ptr, ref); + SAVE_OPLINE(); + if (GC_DELREF(garbage) == 0) { + rc_dtor_func(garbage); + if (UNEXPECTED(EG(exception))) { + ZVAL_NULL(variable_ptr); + HANDLE_EXCEPTION(); } + } else { + gc_check_possible_root(garbage); + } + } else { + ZVAL_REF(variable_ptr, ref); + } - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + ZEND_VM_REPEAT_OPCODE(ZEND_BIND_GLOBAL); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1; + HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); + zval *result; + op1 = EX_VAR(opline->op1.var); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_CV == IS_CONST); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + ZEND_VM_SMART_BRANCH(result, 0); + } - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CONST == IS_UNUSED) { - zend_use_new_element_for_string(); + if (opline->extended_value) { + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + result = zend_hash_index_find(ht, Z_LVAL_P(op1)); + ZEND_VM_SMART_BRANCH(result, 0); + } + SAVE_OPLINE(); + if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find(ht, Z_STR_P(op1)); - UNDEF_RESULT(); - } else { - dim = RT_CONSTANT(opline, opline->op2); - value = RT_CONSTANT((opline+1), (opline+1)->op1); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + ZEND_VM_SMART_BRANCH(result, 0); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + result = zend_hash_index_find(ht, Z_LVAL_P(op1)); + ZEND_VM_SMART_BRANCH(result, 0); } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = RT_CONSTANT(opline, opline->op2); + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + } else if (Z_TYPE_P(op1) <= IS_FALSE) { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + result = zend_hash_find_known_hash(ht, ZSTR_EMPTY_ALLOC()); + ZEND_VM_SMART_BRANCH(result, 0); + } else { + zend_string *key; + zval key_tmp; + if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find(ht, Z_STR_P(op1)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; + ZEND_VM_SMART_BRANCH(result, 0); } - } else { - zend_use_scalar_as_array(); - dim = RT_CONSTANT(opline, opline->op2); -assign_dim_error: + } + SAVE_OPLINE(); + ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) { + ZVAL_STR(&key_tmp, key); + if (zend_compare(op1, &key_tmp) == 0) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); + + ZEND_VM_SMART_BRANCH(1, 1); } - } + } ZEND_HASH_FOREACH_END(); } - if (IS_CONST != IS_UNUSED) { - } + ZEND_VM_SMART_BRANCH(0, 1); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + /* This is declared below the specializations for MAY_BE_LONG/MAY_BE_DOUBLE so those will be used instead if possible. */ + /* This optimizes $x === SOME_CONST_EXPR and $x === $y for non-refs and non-undef, which can't throw. */ + /* (Infinite recursion when comparing arrays is an uncatchable fatal error) */ + USE_OPLINE + zval *op1, *op2; + bool result; - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = fast_is_identical_function(op1, op2); + /* Free is a no-op for const/cv */ + ZEND_VM_SMART_BRANCH(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; + zval *op1, *op2; + bool result; - SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = fast_is_identical_function(op1, op2); + /* Free is a no-op for const/cv */ + ZEND_VM_SMART_BRANCH(!result, 0); +} - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_CONST == IS_UNUSED) { - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_TMP_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_TMP_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container, *dim, *value; + zend_long offset; + HashTable *ht; - GC_ADDREF(obj); - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } + container = EX_VAR(opline->op1.var); + dim = RT_CONSTANT(opline, opline->op2); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + ht = Z_ARRVAL_P(container); + ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CONST == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = RT_CONSTANT(opline, opline->op2); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = RT_CONSTANT(opline, opline->op2); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - zend_use_scalar_as_array(); - dim = RT_CONSTANT(opline, opline->op2); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } + ZEND_VM_NEXT_OPCODE(); } - } - if (IS_CONST != IS_UNUSED) { + } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; + } + } else { +fetch_dim_r_index_slow: + SAVE_OPLINE(); + if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_undefined_offset(offset); + - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); + zval *container, *dim, *value; + zend_long offset; + HashTable *ht; - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_CONST == IS_UNUSED) { - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } + container = EX_VAR(opline->op1.var); + dim = EX_VAR(opline->op2.var); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); } else { - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + ht = Z_ARRVAL_P(container); + ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); } - if (garbage) { - GC_DTOR_NO_REF(garbage); + } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; } } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } +fetch_dim_r_index_slow: + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); - GC_ADDREF(obj); - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_undefined_offset(offset); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CONST == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = RT_CONSTANT(opline, opline->op2); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = RT_CONSTANT(opline, opline->op2); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = RT_CONSTANT(opline, opline->op2); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_CONST != IS_UNUSED) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; - } + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + div_function(EX_VAR(opline->result.var), op1, op2); - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; + zval *op1, *op2; SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); + op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + pow_function(EX_VAR(opline->result.var), op1, op2); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_CONST == IS_UNUSED) { - value = EX_VAR((opline+1)->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } + + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + op1 = EX_VAR(opline->op1.var); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + + if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_DEREF(value); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_CV == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_CV == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } + } else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else if (IS_CV != IS_CONST && IS_CV != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { + zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); } } else { - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); } - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); } + ZEND_VM_NEXT_OPCODE(); } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); + SAVE_OPLINE(); - GC_ADDREF(obj); - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = ZVAL_UNDEFINED_OP1(); + } + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = ZVAL_UNDEFINED_OP2(); + } + concat_function(EX_VAR(opline->result.var), op1, op2); - value = EX_VAR((opline+1)->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_CV & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CONST == IS_UNUSED) { - zend_use_new_element_for_string(); + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + result = fast_is_identical_function(op1, op2); - UNDEF_RESULT(); - } else { - dim = RT_CONSTANT(opline, opline->op2); - value = EX_VAR((opline+1)->op1.var); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = RT_CONSTANT(opline, opline->op2); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + result = fast_is_not_identical_function(op1, op2); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = RT_CONSTANT(opline, opline->op2); -assign_dim_error: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); + op1 = EX_VAR(opline->op1.var); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; } } } - if (IS_CONST != IS_UNUSED) { + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + op1 = EX_VAR(opline->op1.var); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } } - - - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = RT_CONSTANT(opline, opline->op2); - variable_ptr = EX_VAR(opline->op1.var); - - if (0 || UNEXPECTED(0)) { - zend_refcounted *garbage = NULL; + zval *op1, *op2; + double d1, d2; - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(0)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + op1 = EX_VAR(opline->op1.var); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; } - if (garbage) { - GC_DTOR_NO_REF(garbage); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; + } } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES()); } - - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = RT_CONSTANT(opline, opline->op2); - variable_ptr = EX_VAR(opline->op1.var); - - if (0 || UNEXPECTED(1)) { - zend_refcounted *garbage = NULL; + zval *op1, *op2; + double d1, d2; - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(1)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + op1 = EX_VAR(opline->op1.var); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; } - if (garbage) { - GC_DTOR_NO_REF(garbage); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES()); } - - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *property, *container, *value_ptr; - - SAVE_OPLINE(); - - container = EX_VAR(opline->op1.var); - property = RT_CONSTANT(opline, opline->op2); - - value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + zval *op1, *op2; + double d1, d2; - if (1) { - if (IS_CV == IS_UNUSED) { - if (IS_CONST == IS_CONST) { - zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); } else { - zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); } - } else { - if (IS_CONST == IS_CONST) { - zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; } else { - zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + goto is_not_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; } } - } else { - zend_assign_to_property_reference(container, IS_CV, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); } - - - - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *property, *container, *value_ptr; - - SAVE_OPLINE(); - - container = EX_VAR(opline->op1.var); - property = RT_CONSTANT(opline, opline->op2); - - value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); + zval *op1, *op2; + double d1, d2; - if (1) { - if (IS_CV == IS_UNUSED) { - if (IS_CONST == IS_CONST) { - zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); } else { - zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); } - } else { - if (IS_CONST == IS_CONST) { - zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; } else { - zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + goto is_not_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; } } - } else { - zend_assign_to_property_reference(container, IS_CV, property, IS_CONST, value_ptr OPLINE_CC EXECUTE_DATA_CC); } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + compare_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_XOR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + boolean_xor_function(EX_VAR(opline->result.var), op1, op2); - ZEND_VM_NEXT_OPCODE_EX(1, 2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - zend_string *op1_str, *op2_str, *str; + zval *object; + zval *property; + zval *value; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; + SAVE_OPLINE(); + object = EX_VAR(opline->op1.var); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + do { + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if (IS_CV == IS_CONST || IS_CV == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_op_object; } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); + if (IS_CV == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } - } else if (IS_CV != IS_CONST && IS_CV != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); +assign_op_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_TMP_VAR == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + UNDEF_RESULT(); + break; } } - ZEND_VM_NEXT_OPCODE(); - } + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + zend_reference *ref; - SAVE_OPLINE(); - if (IS_CV == IS_CONST) { - op1_str = Z_STR_P(op1); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - op1_str = zend_string_copy(Z_STR_P(op1)); - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - op1_str = zval_get_string_func(op1); - } - if (IS_CONST == IS_CONST) { - op2_str = Z_STR_P(op2); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - op2_str = zend_string_copy(Z_STR_P(op2)); - } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - } - op2_str = zval_get_string_func(op2); - } - do { - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { - GC_ADDREF(op2_str); + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + zptr = Z_REFVAL_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; + } } - } - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - zend_string_release_ex(op1_str, 0); - break; - } - } - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { - GC_ADDREF(op1_str); + + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + if (prop_info) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_binary_op(zptr, zptr, value OPLINE_CC); } + } while (0); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), zptr); } - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - zend_string_release_ex(op2_str, 0); - break; } + } else { + zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); } - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - - ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CV != IS_CONST) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CONST != IS_CONST) { - zend_string_release_ex(op2_str, 0); + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); } } while (0); + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zval *object; - zend_function *fbc; - zend_class_entry *called_scope; - zend_object *obj; - zend_execute_data *call; - uint32_t call_info; + zval *var_ptr; + zval *value, *container, *dim; + HashTable *ht; SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); - object = EX_VAR(opline->op1.var); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +assign_dim_op_array: + SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); +assign_dim_op_new_array: + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_UNUSED) { + var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); + if (UNEXPECTED(!var_ptr)) { + zend_cannot_add_element(); + goto assign_dim_op_ret_null; + } + } else { + if (IS_TMP_VAR == IS_CONST) { + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); + } else { + var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(!var_ptr)) { + goto assign_dim_op_ret_null; + } + } - if (IS_CONST != IS_CONST) { - function_name = RT_CONSTANT(opline, opline->op2); - } + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - if (IS_CONST != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); break; } - } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - - - HANDLE_EXCEPTION(); - } } - zend_throw_error(NULL, "Method name must be a string"); - - - - - HANDLE_EXCEPTION(); + zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); } while (0); - } - if (IS_CV == IS_UNUSED) { - obj = Z_OBJ_P(object); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + } + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); } else { - do { - if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - } else { - if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - zend_reference *ref = Z_REF_P(object); + if (EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto assign_dim_op_array; + } + } - object = &ref->val; - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - if (IS_CV & IS_VAR) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_ADDREF_P(object); - } - } - break; - } - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - object = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CONST != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + uint8_t old_type; - } - HANDLE_EXCEPTION(); - } - } - if (IS_CONST == IS_CONST) { - function_name = RT_CONSTANT(opline, opline->op2); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + ht = zend_new_array(8); + old_type = Z_TYPE_P(container); + ZVAL_ARR(container, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_op_ret_null; } - zend_invalid_method_call(object, function_name); + } + goto assign_dim_op_new_array; + } else { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); +assign_dim_op_ret_null: + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + zval *value; - HANDLE_EXCEPTION(); + SAVE_OPLINE(); + value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + var_ptr = _get_zval_ptr_cv_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC); + + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; } - } while (0); + } + zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); + } while (0); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } - called_scope = obj->ce; + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else { - zend_object *orig_obj = obj; - if (IS_CONST == IS_CONST) { - function_name = RT_CONSTANT(opline, opline->op2); - } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; + SAVE_OPLINE(); + object = EX_VAR(opline->op1.var); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); + do { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto pre_incdec_object; } - HANDLE_EXCEPTION(); - } - if (IS_CONST == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); - } - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ - if (GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); + if (IS_CV == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - } - - if (IS_CONST != IS_CONST) { - - - } - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { - zend_objects_store_del(obj); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); +pre_incdec_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_TMP_VAR == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + UNDEF_RESULT(); + break; } } - /* call static method */ - obj = (zend_object*)called_scope; - call_info = ZEND_CALL_NESTED_FUNCTION; - } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { - if (IS_CV == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); + zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); + } + } else { + zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); } - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; - } + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, obj); - call->prev_execute_data = EX(call); - EX(call) = call; + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE(); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *varptr, *arg; - - if (IS_CONST == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - uint32_t arg_num; - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; + SAVE_OPLINE(); + object = EX_VAR(opline->op1.var); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - HANDLE_EXCEPTION(); + do { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto post_incdec_object; + } + if (IS_CV == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - } - - varptr = EX_VAR(opline->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(arg); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - - if (IS_CV == IS_CV) { - ZVAL_COPY_DEREF(arg, varptr); - } else /* if (IS_CV == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(varptr))) { - zend_refcounted *ref = Z_COUNTED_P(varptr); - varptr = Z_REFVAL_P(varptr); - ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); +post_incdec_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_TMP_VAR == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; + } + } + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { - ZVAL_COPY_VALUE(arg, varptr); + zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); } - } + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); - ZEND_VM_NEXT_OPCODE(); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_REF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *varptr, *arg; + zval *container, *dim, *value; SAVE_OPLINE(); - if (IS_CONST == IS_CONST) { - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - uint32_t arg_num; - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - - - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); + container = EX_VAR(opline->op1.var); + if (IS_CV & (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); } - - varptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(varptr)) { - Z_ADDREF_P(varptr); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_CV != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_TMP_VAR, BP_VAR_R EXECUTE_DATA_CC); + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } else if (IS_CV == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; + } + } else { +fetch_dim_r_slow: + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); + } } else { - ZVAL_MAKE_REF_EX(varptr, 2); + zend_fetch_dimension_address_read_R(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); } - ZVAL_REF(arg, Z_REF_P(varptr)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *varptr, *arg; - uint32_t arg_num; - - if (IS_CONST == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - + zval *container; - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - arg_num = opline->op2.num; + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + zend_fetch_dimension_address_W(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) { - if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - goto send_var_by_ref; - } - } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { -send_var_by_ref: - varptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(varptr)) { - Z_ADDREF_P(varptr); - } else { - ZVAL_MAKE_REF_EX(varptr, 2); - } - ZVAL_REF(arg, Z_REF_P(varptr)); - +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + zend_fetch_dimension_address_RW(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - varptr = EX_VAR(opline->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(arg); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; - if (IS_CV == IS_CV) { - ZVAL_COPY_DEREF(arg, varptr); - } else /* if (IS_CV == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(varptr))) { - zend_refcounted *ref = Z_COUNTED_P(varptr); + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + /* 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_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - varptr = Z_REFVAL_P(varptr); - ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); - } - } else { - ZVAL_COPY_VALUE(arg, varptr); - } - } - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { +#if 0 USE_OPLINE - zval *expr_ptr, new_expr; +#endif - SAVE_OPLINE(); - if ((IS_CV == IS_VAR || IS_CV == IS_CV) && - UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } else { - ZVAL_MAKE_REF_EX(expr_ptr, 2); + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - - + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - if (IS_CV == IS_TMP_VAR) { - /* pass */ - } else if (IS_CV == IS_CONST) { - Z_TRY_ADDREF_P(expr_ptr); - } else if (IS_CV == IS_CV) { - ZVAL_DEREF(expr_ptr); - Z_TRY_ADDREF_P(expr_ptr); - } else /* if (IS_CV == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(expr_ptr); - - expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - ZVAL_COPY_VALUE(&new_expr, expr_ptr); - expr_ptr = &new_expr; - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } - } + if (IS_TMP_VAR == IS_UNUSED) { + ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - } - - if (IS_CONST != IS_UNUSED) { - zval *offset = RT_CONSTANT(opline, opline->op2); - zend_string *str; - zend_ulong hval; - -add_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_CONST != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index; + if (IS_CV & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); } } -str_index: - zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index: - zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto add_again; - } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { - zval tmp; - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_COPY(&tmp, expr_ptr); - } - zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - /* A userland error handler can do funky things to the expression, so reset it */ - zval_ptr_dtor(expr_ptr); - ZVAL_COPY_VALUE(expr_ptr, &tmp); - } - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(expr_ptr); - HANDLE_EXCEPTION(); - } - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); - goto num_index; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - zend_use_resource_as_offset(offset); - hval = Z_RES_HANDLE_P(offset); - goto num_index; - } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else { - zend_illegal_array_offset_access(offset); - zval_ptr_dtor_nogc(expr_ptr); - } - - - } else { - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { - zend_cannot_add_element(); - zval_ptr_dtor_nogc(expr_ptr); } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zval *array; - uint32_t size; USE_OPLINE + zval *container; SAVE_OPLINE(); - array = EX_VAR(opline->result.var); - if (IS_CV != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); - } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZVAL_ARR(array, zend_new_array(0)); - ZEND_VM_NEXT_OPCODE(); + container = EX_VAR(opline->op1.var); + zend_fetch_dimension_address_UNSET(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; - zval *offset; - zend_ulong hval; - zend_string *key; + void **cache_slot = NULL; SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - offset = RT_CONSTANT(opline, opline->op2); - - do { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; + if (IS_CV & (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); + } -unset_dim_array: - SEPARATE_ARRAY(container); - ht = Z_ARRVAL_P(container); -offset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - key = Z_STR_P(offset); - if (IS_CONST != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(key, hval)) { - goto num_index_dim; - } - } -str_index_dim: - ZEND_ASSERT(ht != &EG(symbol_table)); - zend_hash_del(ht, key); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_dim: - zend_hash_index_del(ht, hval); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto offset_again; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - /* The array may be destroyed while throwing a warning in case the float is not representable as an int. - * Temporarily increase the refcount to detect this situation. */ - GC_TRY_ADDREF(ht); - hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - break; - } - if (EG(exception)) { + if (IS_CV == IS_CONST || + (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if ((IS_CV & IS_CV) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; } - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_NULL) { - key = ZSTR_EMPTY_ALLOC(); - goto str_index_dim; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - zend_use_resource_as_offset(offset); - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - key = ZSTR_EMPTY_ALLOC(); - goto str_index_dim; - } else { - zend_illegal_array_offset_unset(offset); - } - break; - } else if (Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto unset_dim_array; } - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - container = ZVAL_UNDEFINED_OP1(); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { - offset = ZVAL_UNDEFINED_OP2(); - } - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } - Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset); - } else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - } else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) { - zend_throw_error(NULL, "Cannot unset offset in a non-array variable"); - } else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) { - zend_false_to_array_deprecated(); - } - } while (0); + zend_wrong_property_read(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; + } while (0); + } + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; + if (IS_TMP_VAR == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_r_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { +fetch_obj_r_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + prop_offset = prop_info->offset; + goto fetch_obj_r_simple; + } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { + zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; + ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); + ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - zval *offset; - zend_string *name, *tmp_name; + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (IS_CV & IS_CV) { + GC_ADDREF(zobj); + } + if (IS_CV & (IS_CV|IS_VAR|IS_TMP_VAR)) { + call_info |= ZEND_CALL_RELEASE_THIS; + } + zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); + call->prev_execute_data = execute_data; + call->call = NULL; + call->return_value = EX_VAR(opline->result.var); + call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - offset = RT_CONSTANT(opline, opline->op2); + execute_data = call; + EG(current_execute_data) = execute_data; + zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); - do { - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - if (Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (Z_TYPE_P(container) != IS_OBJECT) { - if (IS_CV == IS_CV - && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); +#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) + opline = hook->op_array.opcodes; +#else + EX(opline) = hook->op_array.opcodes; +#endif + LOAD_OPLINE_EX(); + + + + + ZEND_VM_ENTER_EX(); + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } } - break; } - } else { - break; } - } - if (IS_CONST == IS_CONST) { - name = Z_STR_P(offset); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(offset, &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); break; } } - Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - if (IS_CONST != IS_CONST) { + +#if ZEND_DEBUG + /* For non-standard object handlers, verify a declared property type in debug builds. + * Fetch prop_info before calling read_property(), as it may deallocate the object. */ + zend_property_info *prop_info = NULL; + if (zobj->handlers->read_property != zend_std_read_property) { + prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); + } +#endif + retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO + && ZEND_TYPE_IS_SET(prop_info->type)) { + ZVAL_OPT_DEREF(retval); + zend_verify_property_type(prop_info, retval, /* strict */ true); + } +#endif + + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } + + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_r_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } } while (0); +fetch_obj_r_finish: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *property, *container, *result; + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + zend_fetch_property_address( + result, container, IS_CV, property, IS_TMP_VAR, + ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - bool result; - zend_ulong hval; - zval *offset; + zval *property, *container, *result; SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - offset = RT_CONSTANT(opline, opline->op2); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + zend_fetch_property_address(result, container, IS_CV, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; - zval *value; - zend_string *str; +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + void **cache_slot = NULL; -isset_dim_obj_array: - ht = Z_ARRVAL_P(container); -isset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_CONST != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index_prop; + SAVE_OPLINE(); + container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ + + if (IS_CV == IS_CONST || + (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; } } - value = zend_hash_find_ex(ht, str, IS_CONST == IS_CONST); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_prop: - value = zend_hash_index_find(ht, hval); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { - offset = Z_REFVAL_P(offset); - goto isset_again; - } else { - value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); - if (UNEXPECTED(EG(exception))) { - result = 0; - goto isset_dim_obj_exit; + if (IS_TMP_VAR == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); } - } - - if (!(opline->extended_value & ZEND_ISEMPTY)) { - /* > IS_NULL means not IS_UNDEF and not IS_NULL */ - result = value != NULL && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - - if (IS_CV & (IS_CONST|IS_CV)) { - /* avoid exception check */ - - - ZEND_VM_SMART_BRANCH(result, 0); - } - } else { - result = (value == NULL || !i_zend_is_true(value)); - } - goto isset_dim_obj_exit; - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto isset_dim_obj_array; - } - } - - if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - if (!(opline->extended_value & ZEND_ISEMPTY)) { - result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); - } else { - result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; + } while (0); } -isset_dim_obj_exit: - - + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; + if (IS_TMP_VAR == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value); - ZEND_VM_SMART_BRANCH(result, 1); -} + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - int result; - zval *offset; - zend_string *name, *tmp_name; + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_is_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { +fetch_obj_is_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + goto fetch_obj_is_simple; + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); - SAVE_OPLINE(); - container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); - offset = RT_CONSTANT(opline, opline->op2); + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); - if (IS_CV == IS_CONST || - (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } + } + } } + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } - } - - if (IS_CONST == IS_CONST) { - name = Z_STR_P(offset); - } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - result = 0; - goto isset_object_finish; + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; + } } - } - - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); -isset_object_finish: + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_is_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } + } while (0); +fetch_obj_is_finish: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { +#if 0 USE_OPLINE +#endif - zval *key, *subject; - HashTable *ht; - bool result; - - SAVE_OPLINE(); - - key = EX_VAR(opline->op1.var); - subject = RT_CONSTANT(opline, opline->op2); - - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { -array_key_exists_array: - ht = Z_ARRVAL_P(subject); - result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + /* Behave like FETCH_OBJ_W */ + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { - subject = Z_REFVAL_P(subject); - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { - goto array_key_exists_array; + if (IS_CV == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } } } - zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); - result = 0; + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - - - - - ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *expr; - bool result; + zval *container, *property, *result; SAVE_OPLINE(); - expr = EX_VAR(opline->op1.var); - -try_instanceof: - if (Z_TYPE_P(expr) == IS_OBJECT) { - zend_class_entry *ce; - - if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(opline->extended_value); - if (UNEXPECTED(ce == NULL)) { - ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (EXPECTED(ce)) { - CACHE_PTR(opline->extended_value, ce); - } - } - } else if (IS_CONST == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - - - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - result = ce && instanceof_function(Z_OBJCE_P(expr), ce); - } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { - expr = Z_REFVAL_P(expr); - goto try_instanceof; - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - result = 0; + container = EX_VAR(opline->op1.var); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + zend_fetch_property_address(result, container, IS_CV, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } - - - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); + object = EX_VAR(opline->op1.var); + value = RT_CONSTANT((opline+1), (opline+1)->op1); - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; + } + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } - /* Set the new yielded value */ - if (IS_CV != IS_UNUSED) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_CV & (IS_CONST|IS_TMP_VAR)) { - zval *value; +assign_object: + zobj = Z_OBJ_P(object); + if (IS_TMP_VAR == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; } } - } else { - zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - do { - if (IS_CV == IS_VAR) { - ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION - && !Z_ISREF_P(value_ptr)) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - ZVAL_COPY(&generator->value, value_ptr); - break; + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); } + zobj->properties = zend_array_dup(zobj->properties); } - if (Z_ISREF_P(value_ptr)) { - Z_ADDREF_P(value_ptr); - } else { - ZVAL_MAKE_REF_EX(value_ptr, 2); + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; } - ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); - } while (0); - - - } - } else { - zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - - /* Consts, temporary variables and references need copying */ - if (IS_CV == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); } - } else if (IS_CV == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CONST != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CONST == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CONST == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CV == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; } + /* Fall through to write_property for hooks. */ } } + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); - } + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { - /* Set the new yielded key */ - if (IS_CONST != IS_UNUSED) { - zval *key = RT_CONSTANT(opline, opline->op2); - if ((IS_CONST & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { - key = Z_REFVAL_P(key); + + UNDEF_RESULT(); + goto exit_assign_obj; } - ZVAL_COPY(&generator->key, key); + } + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_DEREF(value); + } - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); - } - } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); } - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); - } else { - generator->send_target = NULL; +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); } - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); - ZEND_VM_RETURN(); +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_string *varname; - zval *value; - zval *variable_ptr; - uintptr_t idx; - zend_reference *ref; - - ZEND_VM_REPEATABLE_OPCODE - - varname = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - - /* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ - idx = (uintptr_t)CACHED_PTR(opline->extended_value) - 1; - if (EXPECTED(idx < EG(symbol_table).nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)EG(symbol_table).arData + idx); + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; - if (EXPECTED(p->key == varname) || - (EXPECTED(p->h == ZSTR_H(varname)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, varname)))) { + SAVE_OPLINE(); + object = EX_VAR(opline->op1.var); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - value = (zval*)p; /* value = &p->val; */ - goto check_indirect; + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; } + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; } - value = zend_hash_find_known_hash(&EG(symbol_table), varname); - if (UNEXPECTED(value == NULL)) { - value = zend_hash_add_new(&EG(symbol_table), varname, &EG(uninitialized_zval)); - idx = (char*)value - (char*)EG(symbol_table).arData; - /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ - CACHE_PTR(opline->extended_value, (void*)(idx + 1)); - } else { - idx = (char*)value - (char*)EG(symbol_table).arData; - /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ - CACHE_PTR(opline->extended_value, (void*)(idx + 1)); -check_indirect: - /* GLOBAL variable may be an INDIRECT pointer to CV */ - if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { - value = Z_INDIRECT_P(value); - if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - ZVAL_NULL(value); - } - } - } +assign_object: + zobj = Z_OBJ_P(object); + if (IS_TMP_VAR == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - if (UNEXPECTED(!Z_ISREF_P(value))) { - ZVAL_MAKE_REF_EX(value, 2); - ref = Z_REF_P(value); - } else { - ref = Z_REF_P(value); - GC_ADDREF(ref); - } - - variable_ptr = EX_VAR(opline->op1.var); - - if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) { - zend_refcounted *garbage = Z_COUNTED_P(variable_ptr); - - ZVAL_REF(variable_ptr, ref); - SAVE_OPLINE(); - if (GC_DELREF(garbage) == 0) { - rc_dtor_func(garbage); - if (UNEXPECTED(EG(exception))) { - ZVAL_NULL(variable_ptr); - HANDLE_EXCEPTION(); - } - } else { - gc_check_possible_root(garbage); - } - } else { - ZVAL_REF(variable_ptr, ref); - } - - ZEND_VM_REPEAT_OPCODE(ZEND_BIND_GLOBAL); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1; - HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); - zval *result; - - op1 = EX_VAR(opline->op1.var); - if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_CV == IS_CONST); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - ZEND_VM_SMART_BRANCH(result, 0); - } - - if (opline->extended_value) { - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - ZEND_VM_SMART_BRANCH(result, 0); - } - SAVE_OPLINE(); - if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - result = zend_hash_find(ht, Z_STR_P(op1)); - - - ZEND_VM_SMART_BRANCH(result, 0); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - - - ZEND_VM_SMART_BRANCH(result, 0); - } - } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - } else if (Z_TYPE_P(op1) <= IS_FALSE) { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - result = zend_hash_find_known_hash(ht, ZSTR_EMPTY_ALLOC()); - ZEND_VM_SMART_BRANCH(result, 0); - } else { - zend_string *key; - zval key_tmp; - - if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - result = zend_hash_find(ht, Z_STR_P(op1)); - - - ZEND_VM_SMART_BRANCH(result, 0); - } - } - - SAVE_OPLINE(); - ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) { - ZVAL_STR(&key_tmp, key); - if (zend_compare(op1, &key_tmp) == 0) { - - - ZEND_VM_SMART_BRANCH(1, 1); - } - } ZEND_HASH_FOREACH_END(); - } - - - ZEND_VM_SMART_BRANCH(0, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - /* This is declared below the specializations for MAY_BE_LONG/MAY_BE_DOUBLE so those will be used instead if possible. */ - /* This optimizes $x === SOME_CONST_EXPR and $x === $y for non-refs and non-undef, which can't throw. */ - /* (Infinite recursion when comparing arrays is an uncatchable fatal error) */ - USE_OPLINE - zval *op1, *op2; - bool result; - - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_identical_function(op1, op2); - /* Free is a no-op for const/cv */ - ZEND_VM_SMART_BRANCH(result, 0); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_identical_function(op1, op2); - /* Free is a no-op for const/cv */ - ZEND_VM_SMART_BRANCH(!result, 0); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container, *dim, *value; - zend_long offset; - HashTable *ht; - - container = EX_VAR(opline->op1.var); - dim = RT_CONSTANT(opline, opline->op2); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_index_array: - if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { - offset = Z_LVAL_P(dim); - } else { - SAVE_OPLINE(); - zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - ht = Z_ARRVAL_P(container); - ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - SAVE_OPLINE(); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_index_array; - } else { - goto fetch_dim_r_index_slow; - } - } else { -fetch_dim_r_index_slow: - SAVE_OPLINE(); - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - -fetch_dim_r_index_undef: - ZVAL_NULL(EX_VAR(opline->result.var)); - SAVE_OPLINE(); - zend_undefined_offset(offset); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container, *dim, *value; - zend_long offset; - HashTable *ht; - - container = EX_VAR(opline->op1.var); - dim = EX_VAR(opline->op2.var); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_index_array: - if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { - offset = Z_LVAL_P(dim); - } else { - SAVE_OPLINE(); - zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - ht = Z_ARRVAL_P(container); - ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - SAVE_OPLINE(); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_index_array; - } else { - goto fetch_dim_r_index_slow; - } - } else { -fetch_dim_r_index_slow: - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - -fetch_dim_r_index_undef: - ZVAL_NULL(EX_VAR(opline->result.var)); - SAVE_OPLINE(); - zend_undefined_offset(offset); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - div_function(EX_VAR(opline->result.var), op1, op2); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - pow_function(EX_VAR(opline->result.var), op1, op2); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - - op1 = EX_VAR(opline->op1.var); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); - - if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if (IS_CV == IS_CONST || IS_CV == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else if (IS_CV != IS_CONST && IS_CV != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { - zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); - } - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } - ZEND_VM_NEXT_OPCODE(); - } else { - SAVE_OPLINE(); - - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = ZVAL_UNDEFINED_OP1(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = ZVAL_UNDEFINED_OP2(); - } - concat_function(EX_VAR(opline->result.var), op1, op2); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - - op1 = EX_VAR(opline->op1.var); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - - op1 = EX_VAR(opline->op1.var); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - - op1 = EX_VAR(opline->op1.var); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - - op1 = EX_VAR(opline->op1.var); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - - op1 = EX_VAR(opline->op1.var); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - - op1 = EX_VAR(opline->op1.var); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - compare_function(EX_VAR(opline->result.var), op1, op2); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_XOR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - boolean_xor_function(EX_VAR(opline->result.var), op1, op2); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object; - zval *property; - zval *value; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; - - SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - do { - value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_op_object; - } - if (IS_CV == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; - } - -assign_op_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - UNDEF_RESULT(); - break; - } - } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - zend_reference *ref; - - do { - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - zptr = Z_REFVAL_P(zptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - if (prop_info) { - /* special case for typed properties */ - zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_binary_op(zptr, zptr, value OPLINE_CC); - } - } while (0); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), zptr); - } - } - } else { - zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - } while (0); - - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - zval *value, *container, *dim; - HashTable *ht; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -assign_dim_op_array: - SEPARATE_ARRAY(container); - ht = Z_ARRVAL_P(container); -assign_dim_op_new_array: - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); - if (UNEXPECTED(!var_ptr)) { - zend_cannot_add_element(); - goto assign_dim_op_ret_null; - } - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); - } else { - var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(!var_ptr)) { - goto assign_dim_op_ret_null; - } - } - - value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - - do { - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); - } while (0); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - } - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - } else { - if (EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto assign_dim_op_array; - } - } - - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(container); - - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); - } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - uint8_t old_type; - - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - ht = zend_new_array(8); - old_type = Z_TYPE_P(container); - ZVAL_ARR(container, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_op_ret_null; - } - } - goto assign_dim_op_new_array; - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); -assign_dim_op_ret_null: - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - zval *value; - - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - var_ptr = _get_zval_ptr_cv_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC); - - do { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); - } while (0); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - } - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; - - SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - do { - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto pre_incdec_object; - } - if (IS_CV == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; - } - -pre_incdec_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - UNDEF_RESULT(); - break; - } - } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); - } - } else { - zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - } while (0); - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; - - SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - do { - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto post_incdec_object; - } - if (IS_CV == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; - } - -post_incdec_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; - } - } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); - } - } else { - zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - } while (0); - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container, *dim, *value; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (IS_CV != IS_CONST) { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R EXECUTE_DATA_CC); - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_array; - } else { - goto fetch_dim_r_slow; - } - } else { -fetch_dim_r_slow: - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); - } - } else { - zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_W(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_RW(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_read_IS(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ -#if 0 - USE_OPLINE -#endif - - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_UNSET(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - void **cache_slot = NULL; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - - if (IS_CV == IS_CONST || - (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - break; - } - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_wrong_property_read(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_r_finish; - } while (0); - } - - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); - - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_r_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { -fetch_obj_r_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - prop_offset = prop_info->offset; - goto fetch_obj_r_simple; - } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { - zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; - ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); - ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); - - uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (IS_CV & IS_CV) { - GC_ADDREF(zobj); - } - if (IS_CV & (IS_CV|IS_VAR|IS_TMP_VAR)) { - call_info |= ZEND_CALL_RELEASE_THIS; - } - zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); - call->prev_execute_data = execute_data; - call->call = NULL; - call->return_value = EX_VAR(opline->result.var); - call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); - - execute_data = call; - EG(current_execute_data) = execute_data; - zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); - -#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) - opline = hook->op_array.opcodes; -#else - EX(opline) = hook->op_array.opcodes; -#endif - LOAD_OPLINE_EX(); - - - - - ZEND_VM_ENTER_EX(); - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); - - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); - - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; - } - } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; - } - } - } - } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; - } - } - -#if ZEND_DEBUG - /* For non-standard object handlers, verify a declared property type in debug builds. - * Fetch prop_info before calling read_property(), as it may deallocate the object. */ - zend_property_info *prop_info = NULL; - if (zobj->handlers->read_property != zend_std_read_property) { - prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); - } -#endif - retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); -#if ZEND_DEBUG - if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { - ZVAL_OPT_DEREF(retval); - zend_verify_property_type(prop_info, retval, /* strict */ true); - } -#endif - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_r_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } - } while (0); - -fetch_obj_r_finish: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *property, *container, *result; - - SAVE_OPLINE(); - - container = EX_VAR(opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address( - result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), - (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *property, *container, *result; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - void **cache_slot = NULL; - - SAVE_OPLINE(); - container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); - - if (IS_CV == IS_CONST || - (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - break; - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - } - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_is_finish; - } while (0); - } - - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value); - - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_is_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { -fetch_obj_is_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - goto fetch_obj_is_simple; - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); - - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); - - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } - } - } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; - } - } - - retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_is_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } - } while (0); - -fetch_obj_is_finish: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ -#if 0 - USE_OPLINE -#endif - - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - /* Behave like FETCH_OBJ_W */ - if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container, *property, *result; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - value = RT_CONSTANT((opline+1), (opline+1)->op1); - - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CONST != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CONST == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_CONST == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - - - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - - -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_TMP_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_TMP_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_TMP_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CV != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CV == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_CV == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - - - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - - -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - value = RT_CONSTANT((opline+1), (opline+1)->op1); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_CONST == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_CONST == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = RT_CONSTANT((opline+1), (opline+1)->op1); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = RT_CONSTANT((opline+1), (opline+1)->op1); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_CONST & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_use_new_element_for_string(); - - - UNDEF_RESULT(); - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = RT_CONSTANT((opline+1), (opline+1)->op1); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - - - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); -assign_dim_error: - - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } - - - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_TMP_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_TMP_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } - - - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } - - - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - value = EX_VAR((opline+1)->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_CV == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_CV == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = EX_VAR((opline+1)->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_CV & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_use_new_element_for_string(); - - - UNDEF_RESULT(); - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = EX_VAR((opline+1)->op1.var); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - - - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); -assign_dim_error: - - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } - - - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *property, *container, *value_ptr; - - SAVE_OPLINE(); - - container = EX_VAR(opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (1) { - if (IS_CV == IS_UNUSED) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } - } else { - zend_assign_to_property_reference(container, IS_CV, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *property, *container, *value_ptr; - - SAVE_OPLINE(); - - container = EX_VAR(opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); - - if (1) { - if (IS_CV == IS_UNUSED) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } - } else { - zend_assign_to_property_reference(container, IS_CV, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - zend_string *op1_str, *op2_str, *str; - - - op1 = EX_VAR(opline->op1.var); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); - - if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if (IS_CV == IS_CONST || IS_CV == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else if (IS_CV != IS_CONST && IS_CV != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if (IS_CV == IS_CONST) { - op1_str = Z_STR_P(op1); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - op1_str = zend_string_copy(Z_STR_P(op1)); - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - op1_str = zval_get_string_func(op1); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - op2_str = Z_STR_P(op2); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - op2_str = zend_string_copy(Z_STR_P(op2)); - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - } - op2_str = zval_get_string_func(op2); - } - do { - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { - GC_ADDREF(op2_str); - } - } - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - zend_string_release_ex(op1_str, 0); - break; - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { - GC_ADDREF(op1_str); - } - } - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - zend_string_release_ex(op2_str, 0); - break; - } - } - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - - ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CV != IS_CONST) { - zend_string_release_ex(op1_str, 0); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release_ex(op2_str, 0); - } - } while (0); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *function_name; - zval *object; - zend_function *fbc; - zend_class_entry *called_scope; - zend_object *obj; - zend_execute_data *call; - uint32_t call_info; - - SAVE_OPLINE(); - - object = EX_VAR(opline->op1.var); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - } - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - - - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Method name must be a string"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - HANDLE_EXCEPTION(); - } while (0); - } - - if (IS_CV == IS_UNUSED) { - obj = Z_OBJ_P(object); - } else { - do { - if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - } else { - if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - zend_reference *ref = Z_REF_P(object); - - object = &ref->val; - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - if (IS_CV & IS_VAR) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_ADDREF_P(object); - } - } - break; - } - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - object = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } - HANDLE_EXCEPTION(); - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - } - zend_invalid_method_call(object, function_name); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - HANDLE_EXCEPTION(); - } - } while (0); - } - - called_scope = obj->ce; - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else { - zend_object *orig_obj = obj; - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - } - - /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); - } - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); - } - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ - if (GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); - } - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - } - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } - - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { - zend_objects_store_del(obj); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - /* call static method */ - obj = (zend_object*)called_scope; - call_info = ZEND_CALL_NESTED_FUNCTION; - } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { - if (IS_CV == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ - } - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; - } - - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, obj); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *expr_ptr, new_expr; - - SAVE_OPLINE(); - if ((IS_CV == IS_VAR || IS_CV == IS_CV) && - UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } else { - ZVAL_MAKE_REF_EX(expr_ptr, 2); - } - - - } else { - expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - if (IS_CV == IS_TMP_VAR) { - /* pass */ - } else if (IS_CV == IS_CONST) { - Z_TRY_ADDREF_P(expr_ptr); - } else if (IS_CV == IS_CV) { - ZVAL_DEREF(expr_ptr); - Z_TRY_ADDREF_P(expr_ptr); - } else /* if (IS_CV == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(expr_ptr); - - expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - ZVAL_COPY_VALUE(&new_expr, expr_ptr); - expr_ptr = &new_expr; - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } - } - } - } - - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - zend_string *str; - zend_ulong hval; - -add_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index; - } - } -str_index: - zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index: - zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto add_again; - } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { - zval tmp; - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_COPY(&tmp, expr_ptr); - } - zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - /* A userland error handler can do funky things to the expression, so reset it */ - zval_ptr_dtor(expr_ptr); - ZVAL_COPY_VALUE(expr_ptr, &tmp); - } - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(expr_ptr); - HANDLE_EXCEPTION(); - } - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); - goto num_index; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - zend_use_resource_as_offset(offset); - hval = Z_RES_HANDLE_P(offset); - goto num_index; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else { - zend_illegal_array_offset_access(offset); - zval_ptr_dtor_nogc(expr_ptr); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } else { - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { - zend_cannot_add_element(); - zval_ptr_dtor_nogc(expr_ptr); - } - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zval *array; - uint32_t size; - USE_OPLINE - - SAVE_OPLINE(); - array = EX_VAR(opline->result.var); - if (IS_CV != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); - } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZVAL_ARR(array, zend_new_array(0)); - ZEND_VM_NEXT_OPCODE(); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - zval *offset; - zend_ulong hval; - zend_string *key; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - do { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; - -unset_dim_array: - SEPARATE_ARRAY(container); - ht = Z_ARRVAL_P(container); -offset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - key = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(key, hval)) { - goto num_index_dim; - } - } -str_index_dim: - ZEND_ASSERT(ht != &EG(symbol_table)); - zend_hash_del(ht, key); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_dim: - zend_hash_index_del(ht, hval); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto offset_again; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - /* The array may be destroyed while throwing a warning in case the float is not representable as an int. - * Temporarily increase the refcount to detect this situation. */ - GC_TRY_ADDREF(ht); - hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - break; - } - if (EG(exception)) { - break; - } - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_NULL) { - key = ZSTR_EMPTY_ALLOC(); - goto str_index_dim; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - zend_use_resource_as_offset(offset); - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - key = ZSTR_EMPTY_ALLOC(); - goto str_index_dim; - } else { - zend_illegal_array_offset_unset(offset); - } - break; - } else if (Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto unset_dim_array; - } - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - container = ZVAL_UNDEFINED_OP1(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { - offset = ZVAL_UNDEFINED_OP2(); - } - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset); - } else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - } else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) { - zend_throw_error(NULL, "Cannot unset offset in a non-array variable"); - } else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) { - zend_false_to_array_deprecated(); - } - } while (0); - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - zval *offset; - zend_string *name, *tmp_name; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - do { - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - if (Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (Z_TYPE_P(container) != IS_OBJECT) { - if (IS_CV == IS_CV - && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - break; - } - } else { - break; - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(offset); - } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - break; - } - } - Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - } while (0); - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - bool result; - zend_ulong hval; - zval *offset; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; - zval *value; - zend_string *str; - -isset_dim_obj_array: - ht = Z_ARRVAL_P(container); -isset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index_prop; - } - } - value = zend_hash_find_ex(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_prop: - value = zend_hash_index_find(ht, hval); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { - offset = Z_REFVAL_P(offset); - goto isset_again; - } else { - value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); - if (UNEXPECTED(EG(exception))) { - result = 0; - goto isset_dim_obj_exit; - } - } - - if (!(opline->extended_value & ZEND_ISEMPTY)) { - /* > IS_NULL means not IS_UNDEF and not IS_NULL */ - result = value != NULL && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - - if (IS_CV & (IS_CONST|IS_CV)) { - /* avoid exception check */ - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 0); - } - } else { - result = (value == NULL || !i_zend_is_true(value)); - } - goto isset_dim_obj_exit; - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto isset_dim_obj_array; - } - } - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - if (!(opline->extended_value & ZEND_ISEMPTY)) { - result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); - } else { - result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); - } - -isset_dim_obj_exit: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - int result; - zval *offset; - zend_string *name, *tmp_name; - - SAVE_OPLINE(); - container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - if (IS_CV == IS_CONST || - (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } - } else { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } - } - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(offset); - } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - result = 0; - goto isset_object_finish; - } - } - - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -isset_object_finish: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *key, *subject; - HashTable *ht; - bool result; - - SAVE_OPLINE(); - - key = EX_VAR(opline->op1.var); - subject = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { -array_key_exists_array: - ht = Z_ARRVAL_P(subject); - result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); - } else { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { - subject = Z_REFVAL_P(subject); - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { - goto array_key_exists_array; - } - } - zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); - result = 0; - } - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - - SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); - - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); - - /* Set the new yielded value */ - if (IS_CV != IS_UNUSED) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_CV & (IS_CONST|IS_TMP_VAR)) { - zval *value; - - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - - value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } - } else { - zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - do { - if (IS_CV == IS_VAR) { - ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION - && !Z_ISREF_P(value_ptr)) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - ZVAL_COPY(&generator->value, value_ptr); - break; - } - } - if (Z_ISREF_P(value_ptr)) { - Z_ADDREF_P(value_ptr); - } else { - ZVAL_MAKE_REF_EX(value_ptr, 2); - } - ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); - } while (0); - - - } - } else { - zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - - /* Consts, temporary variables and references need copying */ - if (IS_CV == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } else if (IS_CV == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - - - } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CV == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } - } - } - } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); - } - - /* Set the new yielded key */ - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *key = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { - key = Z_REFVAL_P(key); - } - ZVAL_COPY(&generator->key, key); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); - } - } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); - } - - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); - } else { - generator->send_target = NULL; - } - - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); - - ZEND_VM_RETURN(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = EX_VAR(opline->op1.var); - - if (0 || UNEXPECTED(0)) { - zend_refcounted *garbage = NULL; - - value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(0)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES()); - } - - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = EX_VAR(opline->op1.var); - - if (0 || UNEXPECTED(1)) { - zend_refcounted *garbage = NULL; - - value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(1)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES()); - } - - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = EX_VAR(opline->op1.var); - - if (0 || UNEXPECTED(0)) { - zend_refcounted *garbage = NULL; - - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(0)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES()); - } - - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = EX_VAR(opline->op1.var); - - if (0 || UNEXPECTED(1)) { - zend_refcounted *garbage = NULL; - - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(1)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES()); - } - - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *variable_ptr; - zval *value_ptr; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - value_ptr = _get_zval_ptr_ptr_var(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = EX_VAR(opline->op1.var); - - if (IS_CV == IS_VAR && - UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) { - - zend_throw_error(NULL, "Cannot assign by reference to an array dimension of an object"); - variable_ptr = &EG(uninitialized_zval); - } else if (IS_VAR == IS_VAR && - opline->extended_value == ZEND_RETURNS_FUNCTION && - UNEXPECTED(!Z_ISREF_P(value_ptr))) { - - variable_ptr = zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_variable_reference(variable_ptr, value_ptr, &garbage); - } - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr); - } - - if (garbage) { - GC_DTOR(garbage); - } - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *expr; - bool result; - - SAVE_OPLINE(); - expr = EX_VAR(opline->op1.var); - -try_instanceof: - if (Z_TYPE_P(expr) == IS_OBJECT) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(opline->extended_value); - if (UNEXPECTED(ce == NULL)) { - ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (EXPECTED(ce)) { - CACHE_PTR(opline->extended_value, ce); - } - } - } else if (IS_VAR == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - - - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - result = ce && instanceof_function(Z_OBJCE_P(expr), ce); - } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { - expr = Z_REFVAL_P(expr); - goto try_instanceof; - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - result = 0; - } - - - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var_ptr; - zval *value, *container, *dim; - HashTable *ht; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -assign_dim_op_array: - SEPARATE_ARRAY(container); - ht = Z_ARRVAL_P(container); -assign_dim_op_new_array: - dim = NULL; - if (IS_UNUSED == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); - if (UNEXPECTED(!var_ptr)) { - zend_cannot_add_element(); - goto assign_dim_op_ret_null; - } - } else { - if (IS_UNUSED == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); - } else { - var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(!var_ptr)) { - goto assign_dim_op_ret_null; - } - } - - value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - - do { - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); - } while (0); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); - } - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - } else { - if (EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto assign_dim_op_array; - } - } - - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(container); - - dim = NULL; - if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); - } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - uint8_t old_type; - - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - ht = zend_new_array(8); - old_type = Z_TYPE_P(container); - ZVAL_ARR(container, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_op_ret_null; - } - } - goto assign_dim_op_new_array; - } else { - dim = NULL; - zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); -assign_dim_op_ret_null: - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - - - - - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_EX int type) -{ - USE_OPLINE - zval *varname; - zval *retval; - zend_string *name, *tmp_name; - HashTable *target_symbol_table; - - SAVE_OPLINE(); - varname = EX_VAR(opline->op1.var); - - if (IS_CV == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - tmp_name = NULL; - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - name = zval_try_get_tmp_string(varname, &tmp_name); - if (UNEXPECTED(!name)) { - if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) { - - - } - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } - - target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); - retval = zend_hash_find_ex(target_symbol_table, name, IS_CV == IS_CONST); - if (retval == NULL) { - if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { -fetch_this: - zend_fetch_this_var(type OPLINE_CC EXECUTE_DATA_CC); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - if (type == BP_VAR_W) { - retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); - } else if (type == BP_VAR_IS || type == BP_VAR_UNSET) { - retval = &EG(uninitialized_zval); - } else { - if (IS_CV == IS_CV) { - /* Keep name alive in case an error handler tries to free it. */ - zend_string_addref(name); - } - zend_error_unchecked(E_WARNING, "Undefined %svariable $%S", - (opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name); - if (type == BP_VAR_RW && !EG(exception)) { - retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); - } else { - retval = &EG(uninitialized_zval); - } - if (IS_CV == IS_CV) { - zend_string_release(name); - } - } - /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ - } else if (Z_TYPE_P(retval) == IS_INDIRECT) { - retval = Z_INDIRECT_P(retval); - if (Z_TYPE_P(retval) == IS_UNDEF) { - if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { - goto fetch_this; - } - if (type == BP_VAR_W) { - ZVAL_NULL(retval); - } else if (type == BP_VAR_IS || type == BP_VAR_UNSET) { - retval = &EG(uninitialized_zval); - } else { - zend_error_unchecked(E_WARNING, "Undefined %svariable $%S", - (opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name); - if (type == BP_VAR_RW && !EG(exception)) { - ZVAL_NULL(retval); - } else { - retval = &EG(uninitialized_zval); - } - } - } - } - - if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) { - - - } - - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - - ZEND_ASSERT(retval != NULL); - if (type == BP_VAR_R || type == BP_VAR_IS) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else { - ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_R_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - int fetch_type = - (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ? - BP_VAR_W : BP_VAR_R; - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX fetch_type)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_UNSET_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_IS_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS)); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_W(container, NULL, IS_UNUSED OPLINE_CC EXECUTE_DATA_CC); - - - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_RW(container, NULL, IS_UNUSED OPLINE_CC EXECUTE_DATA_CC); - - - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ -#if 0 - USE_OPLINE -#endif - - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - if (IS_UNUSED == IS_UNUSED) { - ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_UNUSED == IS_UNUSED) { - value = RT_CONSTANT((opline+1), (opline+1)->op1); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_CONST == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_CONST == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = NULL; - if (IS_UNUSED == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = RT_CONSTANT((opline+1), (opline+1)->op1); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = NULL; - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = RT_CONSTANT((opline+1), (opline+1)->op1); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_CONST & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_UNUSED == IS_UNUSED) { - zend_use_new_element_for_string(); - - - UNDEF_RESULT(); - } else { - dim = NULL; - value = RT_CONSTANT((opline+1), (opline+1)->op1); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - - - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = NULL; - - - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = NULL; -assign_dim_error: - - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_UNUSED != IS_UNUSED) { - - - } - - - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_UNUSED == IS_UNUSED) { - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_TMP_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_TMP_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = NULL; - if (IS_UNUSED == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = NULL; - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_UNUSED == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = NULL; - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = NULL; - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = NULL; -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_UNUSED != IS_UNUSED) { - - - } - - - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_UNUSED == IS_UNUSED) { - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = NULL; - if (IS_UNUSED == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = NULL; - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_UNUSED == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = NULL; - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = NULL; - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = NULL; -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_UNUSED != IS_UNUSED) { - - - } - - - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_UNUSED == IS_UNUSED) { - value = EX_VAR((opline+1)->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_CV == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_CV == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = NULL; - if (IS_UNUSED == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = NULL; - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = EX_VAR((opline+1)->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_CV & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_UNUSED == IS_UNUSED) { - zend_use_new_element_for_string(); - - - UNDEF_RESULT(); - } else { - dim = NULL; - value = EX_VAR((opline+1)->op1.var); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - - - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = NULL; - - - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = NULL; -assign_dim_error: - - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_UNUSED != IS_UNUSED) { - - - } - - - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - if (IS_CV == IS_UNUSED) { - SAVE_OPLINE(); - zend_verify_missing_return_type(EX(func)); - HANDLE_EXCEPTION(); - } else { -/* prevents "undefined variable opline" errors */ -#if 0 || (IS_CV != IS_UNUSED) - USE_OPLINE - zval *retval_ref, *retval_ptr; - zend_arg_info *ret_info = EX(func)->common.arg_info - 1; - retval_ref = retval_ptr = EX_VAR(opline->op1.var); - - if (IS_CV == IS_CONST) { - ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr); - retval_ref = retval_ptr = EX_VAR(opline->result.var); - } else if (IS_CV == IS_VAR) { - if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) { - retval_ref = retval_ptr = Z_INDIRECT_P(retval_ptr); - } - ZVAL_DEREF(retval_ptr); - } else if (IS_CV == IS_CV) { - ZVAL_DEREF(retval_ptr); - } - - if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { - ZEND_VM_NEXT_OPCODE(); - } - - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { - SAVE_OPLINE(); - retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { - ZEND_VM_NEXT_OPCODE(); - } - } - - zend_reference *ref = NULL; - if (UNEXPECTED(retval_ref != retval_ptr)) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - ref = Z_REF_P(retval_ref); - } else { - /* A cast might happen - unwrap the reference if this is a by-value return */ - if (Z_REFCOUNT_P(retval_ref) == 1) { - ZVAL_UNREF(retval_ref); - } else { - Z_DELREF_P(retval_ref); - ZVAL_COPY(retval_ref, retval_ptr); - } - retval_ptr = retval_ref; - } - } - - SAVE_OPLINE(); - if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, 1, 0))) { - zend_verify_return_error(EX(func), retval_ptr); - HANDLE_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); -#endif - } -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr, *arg; - - if (IS_UNUSED == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - uint32_t arg_num; - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - - - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - } - - varptr = EX_VAR(opline->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(arg); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - - if (IS_CV == IS_CV) { - ZVAL_COPY_DEREF(arg, varptr); - } else /* if (IS_CV == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(varptr))) { - zend_refcounted *ref = Z_COUNTED_P(varptr); - - varptr = Z_REFVAL_P(varptr); - ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); - } - } else { - ZVAL_COPY_VALUE(arg, varptr); - } - } - - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_REF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr, *arg; - - SAVE_OPLINE(); - if (IS_UNUSED == IS_CONST) { - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - uint32_t arg_num; - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - - - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - } - - varptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(varptr)) { - Z_ADDREF_P(varptr); - } else { - ZVAL_MAKE_REF_EX(varptr, 2); - } - ZVAL_REF(arg, Z_REF_P(varptr)); - - - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr, *arg; - uint32_t arg_num; - - if (IS_UNUSED == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - - - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - arg_num = opline->op2.num; - } - - if (EXPECTED(0)) { - if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - goto send_var_by_ref; - } - } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { -send_var_by_ref: - varptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(varptr)) { - Z_ADDREF_P(varptr); - } else { - ZVAL_MAKE_REF_EX(varptr, 2); - } - ZVAL_REF(arg, Z_REF_P(varptr)); - - - ZEND_VM_NEXT_OPCODE(); - } - - varptr = EX_VAR(opline->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(arg); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - - if (IS_CV == IS_CV) { - ZVAL_COPY_DEREF(arg, varptr); - } else /* if (IS_CV == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(varptr))) { - zend_refcounted *ref = Z_COUNTED_P(varptr); - - varptr = Z_REFVAL_P(varptr); - ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); - } - } else { - ZVAL_COPY_VALUE(arg, varptr); - } - } - - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr, *arg; - uint32_t arg_num; - - if (IS_UNUSED == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - - - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - arg_num = opline->op2.num; - } - - if (EXPECTED(1)) { - if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - goto send_var_by_ref; - } - } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { -send_var_by_ref: - varptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(varptr)) { - Z_ADDREF_P(varptr); - } else { - ZVAL_MAKE_REF_EX(varptr, 2); - } - ZVAL_REF(arg, Z_REF_P(varptr)); - - - ZEND_VM_NEXT_OPCODE(); - } - - varptr = EX_VAR(opline->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(arg); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - - if (IS_CV == IS_CV) { - ZVAL_COPY_DEREF(arg, varptr); - } else /* if (IS_CV == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(varptr))) { - zend_refcounted *ref = Z_COUNTED_P(varptr); - - varptr = Z_REFVAL_P(varptr); - ZVAL_COPY_VALUE(arg, varptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); - } - } else { - ZVAL_COPY_VALUE(arg, varptr); - } - } - - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *expr_ptr, new_expr; - - SAVE_OPLINE(); - if ((IS_CV == IS_VAR || IS_CV == IS_CV) && - UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - if (Z_ISREF_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } else { - ZVAL_MAKE_REF_EX(expr_ptr, 2); - } - - - } else { - expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - if (IS_CV == IS_TMP_VAR) { - /* pass */ - } else if (IS_CV == IS_CONST) { - Z_TRY_ADDREF_P(expr_ptr); - } else if (IS_CV == IS_CV) { - ZVAL_DEREF(expr_ptr); - Z_TRY_ADDREF_P(expr_ptr); - } else /* if (IS_CV == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(expr_ptr); - - expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - ZVAL_COPY_VALUE(&new_expr, expr_ptr); - expr_ptr = &new_expr; - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } - } - } - } - - if (IS_UNUSED != IS_UNUSED) { - zval *offset = NULL; - zend_string *str; - zend_ulong hval; - -add_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_UNUSED != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index; - } - } -str_index: - zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index: - zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto add_again; - } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { - zval tmp; - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_COPY(&tmp, expr_ptr); - } - zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - /* A userland error handler can do funky things to the expression, so reset it */ - zval_ptr_dtor(expr_ptr); - ZVAL_COPY_VALUE(expr_ptr, &tmp); - } - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(expr_ptr); - HANDLE_EXCEPTION(); - } - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); - goto num_index; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - zend_use_resource_as_offset(offset); - hval = Z_RES_HANDLE_P(offset); - goto num_index; - } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else { - zend_illegal_array_offset_access(offset); - zval_ptr_dtor_nogc(expr_ptr); - } - - - } else { - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { - zend_cannot_add_element(); - zval_ptr_dtor_nogc(expr_ptr); - } - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zval *array; - uint32_t size; - USE_OPLINE - - SAVE_OPLINE(); - array = EX_VAR(opline->result.var); - if (IS_CV != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); - } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZVAL_ARR(array, zend_new_array(0)); - ZEND_VM_NEXT_OPCODE(); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_CV_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *var = EX_VAR(opline->op1.var); - - if (Z_REFCOUNTED_P(var)) { - zend_refcounted *garbage = Z_COUNTED_P(var); - - ZVAL_UNDEF(var); - SAVE_OPLINE(); - GC_DTOR(garbage); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZVAL_UNDEF(var); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varname; - zend_string *name, *tmp_name; - HashTable *target_symbol_table; - - SAVE_OPLINE(); - - varname = EX_VAR(opline->op1.var); - - if (IS_CV == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - tmp_name = NULL; - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = ZVAL_UNDEFINED_OP1(); - } - name = zval_try_get_tmp_string(varname, &tmp_name); - if (UNEXPECTED(!name)) { - - - HANDLE_EXCEPTION(); - } - } - - target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); - zend_hash_del_ind(target_symbol_table, name); - - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */ -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - - value = EX_VAR(opline->op1.var); - if (!(0)) { - if (Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL)) { - ZEND_VM_SMART_BRANCH_TRUE(); - } else { - ZEND_VM_SMART_BRANCH_FALSE(); - } - } else { - bool result; - - SAVE_OPLINE(); - result = !i_zend_is_true(value); - ZEND_VM_SMART_BRANCH(result, 1); - } -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - - value = EX_VAR(opline->op1.var); - if (!(1)) { - if (Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL)) { - ZEND_VM_SMART_BRANCH_TRUE(); - } else { - ZEND_VM_SMART_BRANCH_FALSE(); - } - } else { - bool result; - - SAVE_OPLINE(); - result = !i_zend_is_true(value); - ZEND_VM_SMART_BRANCH(result, 1); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - bool result; - zval *varname; - zend_string *name, *tmp_name; - HashTable *target_symbol_table; - - SAVE_OPLINE(); - varname = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); - if (IS_CV == IS_CONST) { - name = Z_STR_P(varname); - } else { - name = zval_get_tmp_string(varname, &tmp_name); - } - - target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); - value = zend_hash_find_ex(target_symbol_table, name, IS_CV == IS_CONST); - - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - - - if (!value) { - result = (opline->extended_value & ZEND_ISEMPTY); - } else { - if (Z_TYPE_P(value) == IS_INDIRECT) { - value = Z_INDIRECT_P(value); - } - if (!(opline->extended_value & ZEND_ISEMPTY)) { - if (Z_ISREF_P(value)) { - value = Z_REFVAL_P(value); - } - result = Z_TYPE_P(value) > IS_NULL; - } else { - result = !i_zend_is_true(value); - } - } - - ZEND_VM_SMART_BRANCH(result, true); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *expr; - bool result; - - SAVE_OPLINE(); - expr = EX_VAR(opline->op1.var); - -try_instanceof: - if (Z_TYPE_P(expr) == IS_OBJECT) { - zend_class_entry *ce; + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(opline->extended_value); - if (UNEXPECTED(ce == NULL)) { - ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (EXPECTED(ce)) { - CACHE_PTR(opline->extended_value, ce); +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } } - } - } else if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - - - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - result = ce && instanceof_function(Z_OBJCE_P(expr), ce); - } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { - expr = Z_REFVAL_P(expr); - goto try_instanceof; - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - result = 0; - } - - - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - - SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); - - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); - - /* Set the new yielded value */ - if (IS_CV != IS_UNUSED) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_CV & (IS_CONST|IS_TMP_VAR)) { - zval *value; - - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - - value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; } } - } else { - zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - do { - if (IS_CV == IS_VAR) { - ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION - && !Z_ISREF_P(value_ptr)) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - ZVAL_COPY(&generator->value, value_ptr); - break; + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); } + zobj->properties = zend_array_dup(zobj->properties); } - if (Z_ISREF_P(value_ptr)) { - Z_ADDREF_P(value_ptr); - } else { - ZVAL_MAKE_REF_EX(value_ptr, 2); + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; } - ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); - } while (0); - - - } - } else { - zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - - /* Consts, temporary variables and references need copying */ - if (IS_CV == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } else if (IS_CV == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - - - } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CV == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - } - } - } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); - } - - /* Set the new yielded key */ - if (IS_UNUSED != IS_UNUSED) { - zval *key = NULL; - if ((IS_UNUSED & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { - key = Z_REFVAL_P(key); - } - ZVAL_COPY(&generator->key, key); - - - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); - } - } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); - } - - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); - } else { - generator->send_target = NULL; - } - - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); - - ZEND_VM_RETURN(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CHECK_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1 = EX_VAR(opline->op1.var); - - if (UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MAKE_REF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1 = EX_VAR(opline->op1.var); - - if (IS_CV == IS_CV) { - if (UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_NEW_EMPTY_REF(op1); - Z_SET_REFCOUNT_P(op1, 2); - ZVAL_NULL(Z_REFVAL_P(op1)); - ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); - } else { - if (Z_ISREF_P(op1)) { - Z_ADDREF_P(op1); - } else { - ZVAL_MAKE_REF_EX(op1, 2); - } - ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_INDIRECT)) { - op1 = Z_INDIRECT_P(op1); - if (EXPECTED(!Z_ISREF_P(op1))) { - ZVAL_MAKE_REF_EX(op1, 2); - } else { - GC_ADDREF(Z_REF_P(op1)); - } - ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); - } else { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), op1); - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1; - zend_long count; - - SAVE_OPLINE(); - op1 = EX_VAR(opline->op1.var); - - while (1) { - if (Z_TYPE_P(op1) == IS_ARRAY) { - count = zend_hash_num_elements(Z_ARRVAL_P(op1)); - break; - } else if (Z_TYPE_P(op1) == IS_OBJECT) { - zend_object *zobj = Z_OBJ_P(op1); - /* first, we check if the handler is defined */ - if (zobj->handlers->count_elements) { - if (SUCCESS == zobj->handlers->count_elements(zobj, &count)) { - break; - } - if (UNEXPECTED(EG(exception))) { - count = 0; - break; + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_TMP_VAR == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_TMP_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; } - } - - /* if not and the object implements Countable we call its count() method */ - if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) { - zval retval; - - zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT)); - zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval); - count = zval_get_long(&retval); - zval_ptr_dtor(&retval); - break; - } - - /* If There's no handler and it doesn't implement Countable then emit a TypeError */ - } else if ((IS_CV & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - continue; - } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - count = 0; - zend_type_error("%s(): Argument #1 ($value) must be of type Countable|array, %s given", opline->extended_value ? "sizeof" : "count", zend_zval_value_name(op1)); - break; - } - - ZVAL_LONG(EX_VAR(opline->result.var), count); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COUNT_ARRAY_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_array *ht = Z_ARRVAL_P(EX_VAR(opline->op1.var)); - ZVAL_LONG(EX_VAR(opline->result.var), zend_hash_num_elements(ht)); - if (IS_CV & (IS_TMP_VAR|IS_VAR) && !(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - SAVE_OPLINE(); - zend_array_destroy(ht); - if (EG(exception)) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_CLASS_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - if (IS_CV == IS_UNUSED) { - SAVE_OPLINE(); - if (UNEXPECTED(!EX(func)->common.scope)) { - zend_throw_error(NULL, "get_class() without arguments must be called from within a class"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } else { - zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated"); - ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); - } - } else { - zval *op1; - - SAVE_OPLINE(); - op1 = EX_VAR(opline->op1.var); - while (1) { - if (Z_TYPE_P(op1) == IS_OBJECT) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); - } else if ((IS_CV & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - continue; } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_type_error("get_class(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(op1)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - } - break; - } - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_TYPE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1; - zend_string *type; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - type = zend_zval_get_legacy_type(op1); - if (EXPECTED(type)) { - ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type); + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ + } + } + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - ZVAL_STRING(EX_VAR(opline->result.var), "unknown type"); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + goto exit_assign_obj; + } } - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varptr, *arg; - uint32_t arg_num = opline->op2.num; - - if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_DEREF(value); } - varptr = EX_VAR(opline->op1.var); - arg = ZEND_CALL_VAR(EX(call), opline->result.var); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if (IS_CV == IS_CV) { - ZVAL_COPY(arg, varptr); - } else /* if (IS_CV == IS_VAR) */ { - ZVAL_COPY_VALUE(arg, varptr); + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - div_function(EX_VAR(opline->result.var), op1, op2); - - +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - pow_function(EX_VAR(opline->result.var), op1, op2); - - - + object = EX_VAR(opline->op1.var); + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; + } + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; +assign_object: + zobj = Z_OBJ_P(object); + if (IS_TMP_VAR == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } - if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CV == IS_CONST || IS_CV == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if (IS_CV == IS_CONST || IS_CV == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CV != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CV == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CV == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else if (IS_CV != IS_CONST && IS_CV != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { - zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); - } - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ } } - ZEND_VM_NEXT_OPCODE(); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - SAVE_OPLINE(); - - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = ZVAL_UNDEFINED_OP1(); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = ZVAL_UNDEFINED_OP2(); - } - concat_function(EX_VAR(opline->result.var), op1, op2); - - + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + UNDEF_RESULT(); + goto exit_assign_obj; + } } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - - - - - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - - - - - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_DEREF(value); } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; + SAVE_OPLINE(); + orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_TMP_VAR == IS_UNUSED) { + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; + } } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_DEREF(value); } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_CONST == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } else if (IS_CONST == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } } - if (!result) { - goto is_not_equal_true; + } else { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { - goto is_not_equal_false; + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; + value = RT_CONSTANT((opline+1), (opline+1)->op1); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; + + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_CONST & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - compare_function(EX_VAR(opline->result.var), op1, op2); + + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_TMP_VAR == IS_UNUSED) { + zend_use_new_element_for_string(); + UNDEF_RESULT(); + } else { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + value = RT_CONSTANT((opline+1), (opline+1)->op1); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - boolean_xor_function(EX_VAR(opline->result.var), op1, op2); + UNDEF_RESULT(); + } else { + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + goto try_assign_dim_array; + } + } else { + zend_use_scalar_as_array(); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); +assign_dim_error: + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + if (IS_TMP_VAR != IS_UNUSED) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object; - zval *property; + zval *object_ptr, *orig_object_ptr; zval *value; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - - do { - value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); + orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_op_object; + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_TMP_VAR == IS_UNUSED) { + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; + } } - if (IS_CV == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_DEREF(value); } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_TMP_VAR == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } else if (IS_TMP_VAR == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } + } else { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); -assign_op_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { + GC_ADDREF(obj); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_TMP_VAR == IS_UNUSED) { + zend_use_new_element_for_string(); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); - break; + } else { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } - } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); } else { - zend_reference *ref; - - do { - if (UNEXPECTED(Z_ISREF_P(zptr))) { - ref = Z_REF_P(zptr); - zptr = Z_REFVAL_P(zptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } - } + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - if (prop_info) { - /* special case for typed properties */ - zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_binary_op(zptr, zptr, value OPLINE_CC); + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; } - } while (0); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), zptr); } + goto try_assign_dim_array; } } else { - zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); - } - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + zend_use_scalar_as_array(); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); +assign_dim_error: + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } - } while (0); - - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - - + } + if (IS_TMP_VAR != IS_UNUSED) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } - /* assign_obj has two opcodes! */ + /* assign_dim has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; - zval *value, *container, *dim; - HashTable *ht; + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); + orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -assign_dim_op_array: - SEPARATE_ARRAY(container); - ht = Z_ARRVAL_P(container); -assign_dim_op_new_array: - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_UNUSED) { - var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); - if (UNEXPECTED(!var_ptr)) { - zend_cannot_add_element(); - goto assign_dim_op_ret_null; - } - } else { - if (IS_CV == IS_CONST) { - var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); - } else { - var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_TMP_VAR == IS_UNUSED) { + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; + } } - if (UNEXPECTED(!var_ptr)) { - goto assign_dim_op_ret_null; + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_DEREF(value); } - } - - value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - - do { - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_CV == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } else if (IS_CV == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); } } - zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); - } while (0); - + } else { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); + } if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); } - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); } else { - if (EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto assign_dim_op_array; + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; } } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(container); - - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + GC_ADDREF(obj); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); - } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { - uint8_t old_type; - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_CV & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); } - ht = zend_new_array(8); - old_type = Z_TYPE_P(container); - ZVAL_ARR(container, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_op_ret_null; + + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + + + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_TMP_VAR == IS_UNUSED) { + zend_use_new_element_for_string(); + + + UNDEF_RESULT(); + } else { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + value = EX_VAR((opline+1)->op1.var); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + + + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + + UNDEF_RESULT(); + } else { + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } } + goto try_assign_dim_array; } - goto assign_dim_op_new_array; } else { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); -assign_dim_op_ret_null: - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + zend_use_scalar_as_array(); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); +assign_dim_error: + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } } + if (IS_TMP_VAR != IS_UNUSED) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } - - + /* assign_dim has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *var_ptr; zval *value; + zval *variable_ptr; SAVE_OPLINE(); - value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - var_ptr = _get_zval_ptr_cv_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC); + value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = EX_VAR(opline->op1.var); - do { - if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { - zend_reference *ref = Z_REF_P(var_ptr); - var_ptr = Z_REFVAL_P(var_ptr); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; - } - } - zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); - } while (0); + if (0 || UNEXPECTED(0)) { + zend_refcounted *garbage = NULL; - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES()); } - + /* zend_assign_to_variable() always takes care of op2, never free it! */ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; + zval *value; + zval *variable_ptr; SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = EX_VAR(opline->op1.var); - do { - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto pre_incdec_object; - } - if (IS_CV == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; - } + if (0 || UNEXPECTED(1)) { + zend_refcounted *garbage = NULL; -pre_incdec_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - UNDEF_RESULT(); - break; - } - } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } else { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); - } - } else { - zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(1)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); } - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + if (garbage) { + GC_DTOR_NO_REF(garbage); } - } while (0); - + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES()); + } + /* zend_assign_to_variable() always takes care of op2, never free it! */ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object; - zval *property; - zval *zptr; - void *_cache_slot[3] = {0}; - void **cache_slot; - zend_property_info *prop_info; - zend_object *zobj; - zend_string *name, *tmp_name; + zval *property, *container, *value_ptr; SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - do { - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto post_incdec_object; - } - if (IS_CV == IS_CV - && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); - break; - } + container = EX_VAR(opline->op1.var); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); -post_incdec_object: - /* here we are sure we are dealing with an object */ - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - name = Z_STR_P(property); - } else { - name = zval_try_get_tmp_string(property, &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; - } - } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; - if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { - if (UNEXPECTED(Z_ISERROR_P(zptr))) { - ZVAL_NULL(EX_VAR(opline->result.var)); + value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + + if (1) { + if (IS_CV == IS_UNUSED) { + if (IS_TMP_VAR == IS_CONST) { + zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } else { - zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); - } - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + if (IS_TMP_VAR == IS_CONST) { + zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } } - } while (0); - - + } else { + zend_assign_to_property_reference(container, IS_CV, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container, *dim, *value; + zval *property, *container, *value_ptr; SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); - dim = EX_VAR(opline->op2.var); - if (IS_CV != IS_CONST) { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R EXECUTE_DATA_CC); - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_array; + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); + + if (1) { + if (IS_CV == IS_UNUSED) { + if (IS_TMP_VAR == IS_CONST) { + zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { - goto fetch_dim_r_slow; + zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } else { -fetch_dim_r_slow: - if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; + if (IS_TMP_VAR == IS_CONST) { + zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } - zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); } } else { - zend_fetch_dimension_address_read_R(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_property_reference(container, IS_CV, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_W(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); - - - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + zval *op1, *op2; + zend_string *op1_str, *op2_str, *str; -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_RW(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + } else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else if (IS_CV != IS_CONST && IS_CV != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } + ZEND_VM_NEXT_OPCODE(); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_read_IS(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); - - - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ -#if 0 - USE_OPLINE -#endif - - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_CV == IS_CONST) { + op1_str = Z_STR_P(op1); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + op1_str = zend_string_copy(Z_STR_P(op1)); + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + op1_str = zval_get_string_func(op1); + } + if (IS_TMP_VAR == IS_CONST) { + op2_str = Z_STR_P(op2); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + op2_str = zend_string_copy(Z_STR_P(op2)); } else { - if (IS_CV == IS_UNUSED) { - ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + op2_str = zval_get_string_func(op2); } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; + do { + if (IS_CV != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + zend_string_release_ex(op1_str, 0); + break; + } + } + if (IS_TMP_VAR != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + zend_string_release_ex(op2_str, 0); + break; + } + } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_UNSET(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); + ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CV != IS_CONST) { + zend_string_release_ex(op1_str, 0); + } + if (IS_TMP_VAR != IS_CONST) { + zend_string_release_ex(op2_str, 0); + } + } while (0); - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zval *container; - void **cache_slot = NULL; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - - if (IS_CV == IS_CONST || - (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - break; - } - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_wrong_property_read(container, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_r_finish; - } while (0); - } - - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; - - if (IS_CV == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); - - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + USE_OPLINE + zval *function_name; + zval *object; + zend_function *fbc; + zend_class_entry *called_scope; + zend_object *obj; + zend_execute_data *call; + uint32_t call_info; - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_r_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { -fetch_obj_r_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - prop_offset = prop_info->offset; - goto fetch_obj_r_simple; - } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { - zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; - ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); - ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); + SAVE_OPLINE(); - uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (IS_CV & IS_CV) { - GC_ADDREF(zobj); - } - if (IS_CV & (IS_CV|IS_VAR|IS_TMP_VAR)) { - call_info |= ZEND_CALL_RELEASE_THIS; - } - zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); - call->prev_execute_data = execute_data; - call->call = NULL; - call->return_value = EX_VAR(opline->result.var); - call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); + object = EX_VAR(opline->op1.var); - execute_data = call; - EG(current_execute_data) = execute_data; - zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); + if (IS_TMP_VAR != IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + } -#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) - opline = hook->op_array.opcodes; -#else - EX(opline) = hook->op_array.opcodes; -#endif - LOAD_OPLINE_EX(); + if (IS_TMP_VAR != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Method name must be a string"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_ENTER_EX(); - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + HANDLE_EXCEPTION(); + } while (0); + } - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + if (IS_CV == IS_UNUSED) { + obj = Z_OBJ_P(object); + } else { + do { + if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + } else { + if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + zend_reference *ref = Z_REF_P(object); - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; - } + object = &ref->val; + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + if (IS_CV & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); } } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + break; } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + object = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_TMP_VAR != IS_CONST) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } + HANDLE_EXCEPTION(); } } + if (IS_TMP_VAR == IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + } + zend_invalid_method_call(object, function_name); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + + HANDLE_EXCEPTION(); } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; - } + } while (0); + } + + called_scope = obj->ce; + + if (IS_TMP_VAR == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else { + zend_object *orig_obj = obj; + + if (IS_TMP_VAR == IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); } -#if ZEND_DEBUG - /* For non-standard object handlers, verify a declared property type in debug builds. - * Fetch prop_info before calling read_property(), as it may deallocate the object. */ - zend_property_info *prop_info = NULL; - if (zobj->handlers->read_property != zend_std_read_property) { - prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); + /* First, locate the function. */ + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + HANDLE_EXCEPTION(); } -#endif - retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); -#if ZEND_DEBUG - if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { - ZVAL_OPT_DEREF(retval); - zend_verify_property_type(prop_info, retval, /* strict */ true); + if (IS_TMP_VAR == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(obj == orig_obj)) { + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } -#endif - - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } } - - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_r_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); } - } while (0); - -fetch_obj_r_finish: + } + if (IS_TMP_VAR != IS_CONST) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; + } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { + if (IS_CV == IS_CV) { + GC_ADDREF(obj); /* For $this pointer */ + } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; + } + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, obj); + call->prev_execute_data = EX(call); + EX(call) = call; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *property, *container, *result; + zval *expr_ptr, new_expr; SAVE_OPLINE(); + if ((IS_CV == IS_VAR || IS_CV == IS_CV) && + UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { + expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } else { + ZVAL_MAKE_REF_EX(expr_ptr, 2); + } - container = EX_VAR(opline->op1.var); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address( - result, container, IS_CV, property, IS_CV, - ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); + } else { + expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + if (IS_CV == IS_TMP_VAR) { + /* pass */ + } else if (IS_CV == IS_CONST) { + Z_TRY_ADDREF_P(expr_ptr); + } else if (IS_CV == IS_CV) { + ZVAL_DEREF(expr_ptr); + Z_TRY_ADDREF_P(expr_ptr); + } else /* if (IS_CV == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(expr_ptr); - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + expr_ptr = Z_REFVAL_P(expr_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + ZVAL_COPY_VALUE(&new_expr, expr_ptr); + expr_ptr = &new_expr; + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } + } + } + } + + if (IS_TMP_VAR != IS_UNUSED) { + zval *offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + zend_string *str; + zend_ulong hval; + +add_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_TMP_VAR != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index; + } + } +str_index: + zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index: + zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto add_again; + } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { + zval tmp; + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_COPY(&tmp, expr_ptr); + } + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + /* A userland error handler can do funky things to the expression, so reset it */ + zval_ptr_dtor(expr_ptr); + ZVAL_COPY_VALUE(expr_ptr, &tmp); + } + if (UNEXPECTED(EG(exception))) { + zval_ptr_dtor_nogc(expr_ptr); + HANDLE_EXCEPTION(); + } + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + goto num_index; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); + hval = Z_RES_HANDLE_P(offset); + goto num_index; + } else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else { + zend_illegal_array_offset_access(offset); + zval_ptr_dtor_nogc(expr_ptr); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } else { + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(expr_ptr); + } } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zval *array; + uint32_t size; USE_OPLINE - zval *property, *container, *result; SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - - - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + array = EX_VAR(opline->result.var); + if (IS_CV != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_ARR(array, zend_new_array(0)); + ZEND_VM_NEXT_OPCODE(); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; - void **cache_slot = NULL; + zval *offset; + zend_ulong hval; + zend_string *key; SAVE_OPLINE(); - container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); + container = EX_VAR(opline->op1.var); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - if (IS_CV == IS_CONST || - (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + do { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + +unset_dim_array: + SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); +offset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + key = Z_STR_P(offset); + if (IS_TMP_VAR != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(key, hval)) { + goto num_index_dim; + } + } +str_index_dim: + ZEND_ASSERT(ht != &EG(symbol_table)); + zend_hash_del(ht, key); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_dim: + zend_hash_index_del(ht, hval); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto offset_again; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + /* The array may be destroyed while throwing a warning in case the float is not representable as an int. + * Temporarily increase the refcount to detect this situation. */ + GC_TRY_ADDREF(ht); + hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); break; } - } - if (IS_CV == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { + if (EG(exception)) { + break; + } + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_NULL) { + key = ZSTR_EMPTY_ALLOC(); + goto str_index_dim; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + } else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); + key = ZSTR_EMPTY_ALLOC(); + goto str_index_dim; + } else { + zend_illegal_array_offset_unset(offset); } - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_is_finish; - } while (0); - } - - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; - - if (IS_CV == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value); + break; + } else if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto unset_dim_array; + } + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + container = ZVAL_UNDEFINED_OP1(); + } + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + offset = ZVAL_UNDEFINED_OP2(); + } + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; + } + Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset); + } else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { + zend_throw_error(NULL, "Cannot unset string offsets"); + } else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) { + zend_throw_error(NULL, "Cannot unset offset in a non-array variable"); + } else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) { + zend_false_to_array_deprecated(); + } + } while (0); - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_is_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { -fetch_obj_is_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - goto fetch_obj_is_simple; - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + zval *offset; + zend_string *name, *tmp_name; + + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + do { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + if (IS_CV == IS_CV + && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } + break; } + } else { + break; } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + } + if (IS_TMP_VAR == IS_CONST) { + name = Z_STR_P(offset); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(offset, &tmp_name); if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); break; } } - - retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if (IS_CV != IS_CONST) { + Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } - - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_is_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } } while (0); -fetch_obj_is_finish: - - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if 0 USE_OPLINE -#endif + zval *container; + bool result; + zend_ulong hval; + zval *offset; - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - /* Behave like FETCH_OBJ_W */ - if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + zval *value; + zend_string *str; + +isset_dim_obj_array: + ht = Z_ARRVAL_P(container); +isset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_TMP_VAR != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_prop; + } + } + value = zend_hash_find_ex(ht, str, IS_TMP_VAR == IS_CONST); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_prop: + value = zend_hash_index_find(ht, hval); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + offset = Z_REFVAL_P(offset); + goto isset_again; + } else { + value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); + if (UNEXPECTED(EG(exception))) { + result = 0; + goto isset_dim_obj_exit; + } + } + + if (!(opline->extended_value & ZEND_ISEMPTY)) { + /* > IS_NULL means not IS_UNDEF and not IS_NULL */ + result = value != NULL && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + + if (IS_CV & (IS_CONST|IS_CV)) { + /* avoid exception check */ + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_SMART_BRANCH(result, 0); + } + } else { + result = (value == NULL || !i_zend_is_true(value)); + } + goto isset_dim_obj_exit; + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto isset_dim_obj_array; } - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container, *property, *result; + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; + } + if (!(opline->extended_value & ZEND_ISEMPTY)) { + result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); + } else { + result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); + } - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); +isset_dim_obj_exit: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (IS_CV == IS_VAR) { - FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; + zval *container; + int result; + zval *offset; zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - value = RT_CONSTANT((opline+1), (opline+1)->op1); + container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; + if (IS_CV == IS_CONST || + (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } + } else { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } - zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; } -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CONST != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CONST == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_CONST == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (IS_TMP_VAR == IS_CONST) { + name = Z_STR_P(offset); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(offset, &tmp_name); if (UNEXPECTED(!name)) { - - - UNDEF_RESULT(); - goto exit_assign_obj; + result = 0; + goto isset_object_finish; } } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - if (IS_CV != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } +isset_object_finish: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } + ZEND_VM_SMART_BRANCH(result, 1); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *key, *subject; + HashTable *ht; + bool result; + SAVE_OPLINE(); - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + key = EX_VAR(opline->op1.var); + subject = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: + ht = Z_ARRVAL_P(subject); + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); + } else { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } + } + zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); + result = 0; + } + + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + + ZEND_VM_SMART_BRANCH(result, 1); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; + SAVE_OPLINE(); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; + /* Set the new yielded value */ + if (IS_CV != IS_UNUSED) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_CV & (IS_CONST|IS_TMP_VAR)) { + zval *value; + + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + + value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); } } + } else { + zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_TMP_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_TMP_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_TMP_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + do { + if (IS_CV == IS_VAR) { + ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION + && !Z_ISREF_P(value_ptr)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + ZVAL_COPY(&generator->value, value_ptr); + break; } } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); + if (Z_ISREF_P(value_ptr)) { + Z_ADDREF_P(value_ptr); + } else { + ZVAL_MAKE_REF_EX(value_ptr, 2); } - goto exit_assign_obj; + ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); + } while (0); + + + } + } else { + zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + + /* Consts, temporary variables and references need copying */ + if (IS_CV == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); } + } else if (IS_CV == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + + } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CV == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } - /* Fall through to write_property for hooks. */ } } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); + } + + /* Set the new yielded key */ + if (IS_TMP_VAR != IS_UNUSED) { + zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + key = Z_REFVAL_P(key); } + ZVAL_COPY(&generator->key, key); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); + } + } else { + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); + } + + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { - ZVAL_DEREF(value); - } + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); + + ZEND_VM_RETURN(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *variable_ptr; + zval *value_ptr; + zend_refcounted *garbage = NULL; + + SAVE_OPLINE(); + value_ptr = _get_zval_ptr_ptr_var(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = EX_VAR(opline->op1.var); - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + if (IS_CV == IS_VAR && + UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) { - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + zend_throw_error(NULL, "Cannot assign by reference to an array dimension of an object"); + variable_ptr = &EG(uninitialized_zval); + } else if (IS_VAR == IS_VAR && + opline->extended_value == ZEND_RETURNS_FUNCTION && + UNEXPECTED(!Z_ISREF_P(value_ptr))) { + + variable_ptr = zend_wrong_assign_to_variable_reference( + variable_ptr, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_variable_reference(variable_ptr, value_ptr, &garbage); } -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr); } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: + if (garbage) { - GC_DTOR_NO_REF(garbage); + GC_DTOR(garbage); } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; + zval *expr; + bool result; SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + expr = EX_VAR(opline->op1.var); - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; +try_instanceof: + if (Z_TYPE_P(expr) == IS_OBJECT) { + zend_class_entry *ce; + + if (IS_VAR == IS_CONST) { + ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (EXPECTED(ce)) { + CACHE_PTR(opline->extended_value, ce); + } + } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } - zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { + expr = Z_REFVAL_P(expr); + goto try_instanceof; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + result = 0; } -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); + ZEND_VM_SMART_BRANCH(result, 1); +} -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var_ptr; + zval *value, *container, *dim; + HashTable *ht; - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +assign_dim_op_array: + SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); +assign_dim_op_new_array: + dim = NULL; + if (IS_UNUSED == IS_UNUSED) { + var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); + if (UNEXPECTED(!var_ptr)) { + zend_cannot_add_element(); + goto assign_dim_op_ret_null; + } + } else { + if (IS_UNUSED == IS_CONST) { + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; + var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(!var_ptr)) { + goto assign_dim_op_ret_null; + } + } + + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); + + do { + if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; } - /* Fall through to write_property for hooks. */ } + zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); + } while (0); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; + if (EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto assign_dim_op_array; + } } - } - - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + dim = NULL; + if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + uint8_t old_type; -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + ht = zend_new_array(8); + old_type = Z_TYPE_P(container); + ZVAL_ARR(container, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_op_ret_null; + } + } + goto assign_dim_op_new_array; + } else { + dim = NULL; + zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); +assign_dim_op_ret_null: + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } } - /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV_EX zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_EX int type) { USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; + zval *varname; + zval *retval; zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; + HashTable *target_symbol_table; SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } + varname = EX_VAR(opline->op1.var); -assign_object: - zobj = Z_OBJ_P(object); if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + name = zval_try_get_tmp_string(varname, &tmp_name); + if (UNEXPECTED(!name)) { + if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) { - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } + } + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_CV != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_CV == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_CV == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } + target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); + retval = zend_hash_find_ex(target_symbol_table, name, IS_CV == IS_CONST); + if (retval == NULL) { + if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { +fetch_this: + zend_fetch_this_var(type OPLINE_CC EXECUTE_DATA_CC); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + if (type == BP_VAR_W) { + retval = zend_hash_add_new(target_symbol_table, name, &EG(uninitialized_zval)); + } else if (type == BP_VAR_IS || type == BP_VAR_UNSET) { + retval = &EG(uninitialized_zval); + } else { + if (IS_CV == IS_CV) { + /* Keep name alive in case an error handler tries to free it. */ + zend_string_addref(name); + } + zend_error_unchecked(E_WARNING, "Undefined %svariable $%S", + (opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name); + if (type == BP_VAR_RW && !EG(exception)) { + retval = zend_hash_update(target_symbol_table, name, &EG(uninitialized_zval)); } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; + retval = &EG(uninitialized_zval); + } + if (IS_CV == IS_CV) { + zend_string_release(name); + } + } + /* GLOBAL or $$name variable may be an INDIRECT pointer to CV */ + } else if (Z_TYPE_P(retval) == IS_INDIRECT) { + retval = Z_INDIRECT_P(retval); + if (Z_TYPE_P(retval) == IS_UNDEF) { + if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { + goto fetch_this; + } + if (type == BP_VAR_W) { + ZVAL_NULL(retval); + } else if (type == BP_VAR_IS || type == BP_VAR_UNSET) { + retval = &EG(uninitialized_zval); + } else { + zend_error_unchecked(E_WARNING, "Undefined %svariable $%S", + (opline->extended_value & ZEND_FETCH_GLOBAL ? "global " : ""), name); + if (type == BP_VAR_RW && !EG(exception)) { + ZVAL_NULL(retval); + } else { + retval = &EG(uninitialized_zval); } - /* Fall through to write_property for hooks. */ } } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { + } + + if (!(opline->extended_value & ZEND_FETCH_GLOBAL_LOCK)) { - UNDEF_RESULT(); - goto exit_assign_obj; - } } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_DEREF(value); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + ZEND_ASSERT(retval != NULL); + if (type == BP_VAR_R || type == BP_VAR_IS) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else { + ZVAL_INDIRECT(EX_VAR(opline->result.var), retval); } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_R_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + int fetch_type = + (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ? + BP_VAR_W : BP_VAR_R; + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX fetch_type)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_UNSET_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_IS_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS)); +} + +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + zend_fetch_dimension_address_W(container, NULL, IS_UNUSED OPLINE_CC EXECUTE_DATA_CC); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + zend_fetch_dimension_address_RW(container, NULL, IS_UNUSED OPLINE_CC EXECUTE_DATA_CC); + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ +#if 0 + USE_OPLINE +#endif - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if (IS_UNUSED == IS_UNUSED) { + ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + if (IS_CV & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object_ptr, *orig_object_ptr; @@ -54812,7 +48791,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: SEPARATE_ARRAY(object_ptr); - if (IS_CV == IS_UNUSED) { + if (IS_UNUSED == IS_UNUSED) { value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { HashTable *ht = Z_ARRVAL_P(object_ptr); @@ -54850,8 +48829,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP } } } else { - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CONST) { + dim = NULL; + if (IS_UNUSED == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); @@ -54879,10 +48858,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_object *obj = Z_OBJ_P(object_ptr); GC_ADDREF(obj); - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = NULL; + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } @@ -54900,13 +48879,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CV == IS_UNUSED) { + if (IS_UNUSED == IS_UNUSED) { zend_use_new_element_for_string(); UNDEF_RESULT(); } else { - dim = EX_VAR(opline->op2.var); + dim = NULL; value = RT_CONSTANT((opline+1), (opline+1)->op1); zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); @@ -54916,7 +48895,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + dim = NULL; UNDEF_RESULT(); @@ -54937,7 +48916,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP } } else { zend_use_scalar_as_array(); - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + dim = NULL; assign_dim_error: @@ -54946,7 +48925,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP } } } - if (IS_CV != IS_UNUSED) { + if (IS_UNUSED != IS_UNUSED) { } @@ -54956,7 +48935,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object_ptr, *orig_object_ptr; @@ -54971,7 +48950,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: SEPARATE_ARRAY(object_ptr); - if (IS_CV == IS_UNUSED) { + if (IS_UNUSED == IS_UNUSED) { value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { HashTable *ht = Z_ARRVAL_P(object_ptr); @@ -55009,8 +48988,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP } } } else { - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CONST) { + dim = NULL; + if (IS_UNUSED == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); @@ -55038,10 +49017,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_object *obj = Z_OBJ_P(object_ptr); GC_ADDREF(obj); - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = NULL; + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } @@ -55059,12 +49038,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CV == IS_UNUSED) { + if (IS_UNUSED == IS_UNUSED) { zend_use_new_element_for_string(); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - dim = EX_VAR(opline->op2.var); + dim = NULL; value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); @@ -55073,162 +49052,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_CV != IS_UNUSED) { - - - } - - - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_CV == IS_UNUSED) { - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CV == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = EX_VAR(opline->op2.var); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + dim = NULL; zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { @@ -55248,7 +49072,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP } } else { zend_use_scalar_as_array(); - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + dim = NULL; assign_dim_error: zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -55256,7 +49080,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP } } } - if (IS_CV != IS_UNUSED) { + if (IS_UNUSED != IS_UNUSED) { } @@ -55266,7 +49090,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object_ptr, *orig_object_ptr; @@ -55281,7 +49105,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: SEPARATE_ARRAY(object_ptr); - if (IS_CV == IS_UNUSED) { + if (IS_UNUSED == IS_UNUSED) { value = EX_VAR((opline+1)->op1.var); if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { HashTable *ht = Z_ARRVAL_P(object_ptr); @@ -55319,8 +49143,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP } } } else { - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CONST) { + dim = NULL; + if (IS_UNUSED == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); @@ -55348,10 +49172,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_object *obj = Z_OBJ_P(object_ptr); GC_ADDREF(obj); - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = NULL; + if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } @@ -55369,13 +49193,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CV == IS_UNUSED) { + if (IS_UNUSED == IS_UNUSED) { zend_use_new_element_for_string(); UNDEF_RESULT(); } else { - dim = EX_VAR(opline->op2.var); + dim = NULL; value = EX_VAR((opline+1)->op1.var); zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); @@ -55385,7 +49209,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + dim = NULL; UNDEF_RESULT(); @@ -55406,7 +49230,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP } } else { zend_use_scalar_as_array(); - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + dim = NULL; assign_dim_error: @@ -55415,7 +49239,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP } } } - if (IS_CV != IS_UNUSED) { + if (IS_UNUSED != IS_UNUSED) { } @@ -55425,474 +49249,287 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SP ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = EX_VAR(opline->op1.var); - - if (0 || UNEXPECTED(0)) { - zend_refcounted *garbage = NULL; - - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(0)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); - } - - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = EX_VAR(opline->op1.var); - - if (0 || UNEXPECTED(1)) { - zend_refcounted *garbage = NULL; - - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(1)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); - } - - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *variable_ptr; - zval *value_ptr; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = EX_VAR(opline->op1.var); - - if (IS_CV == IS_VAR && - UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) { - - zend_throw_error(NULL, "Cannot assign by reference to an array dimension of an object"); - variable_ptr = &EG(uninitialized_zval); - } else if (IS_CV == IS_VAR && - opline->extended_value == ZEND_RETURNS_FUNCTION && - UNEXPECTED(!Z_ISREF_P(value_ptr))) { - - variable_ptr = zend_wrong_assign_to_variable_reference( - variable_ptr, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_variable_reference(variable_ptr, value_ptr, &garbage); - } - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr); - } - - if (garbage) { - GC_DTOR(garbage); - } - - - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *property, *container, *value_ptr; - - SAVE_OPLINE(); - - container = EX_VAR(opline->op1.var); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - - value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (1) { - if (IS_CV == IS_UNUSED) { - if (IS_CV == IS_CONST) { - zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } else { - if (IS_CV == IS_CONST) { - zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } - } else { - zend_assign_to_property_reference(container, IS_CV, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - - - - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zval *property, *container, *value_ptr; - - SAVE_OPLINE(); - - container = EX_VAR(opline->op1.var); - property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - - value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); - - if (1) { - if (IS_CV == IS_UNUSED) { - if (IS_CV == IS_CONST) { - zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } else { - if (IS_CV == IS_CONST) { - zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - } + if (IS_CV == IS_UNUSED) { + SAVE_OPLINE(); + zend_verify_missing_return_type(EX(func)); + HANDLE_EXCEPTION(); } else { - zend_assign_to_property_reference(container, IS_CV, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC); - } - - - - - - - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - zend_string *op1_str, *op2_str, *str; - - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); - - if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CV == IS_CONST || IS_CV == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if (IS_CV == IS_CONST || IS_CV == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else if (IS_CV != IS_CONST && IS_CV != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); +/* prevents "undefined variable opline" errors */ +#if 0 || (IS_CV != IS_UNUSED) + USE_OPLINE + zval *retval_ref, *retval_ptr; + zend_arg_info *ret_info = EX(func)->common.arg_info - 1; + retval_ref = retval_ptr = EX_VAR(opline->op1.var); - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); + if (IS_CV == IS_CONST) { + ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr); + retval_ref = retval_ptr = EX_VAR(opline->result.var); + } else if (IS_CV == IS_VAR) { + if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) { + retval_ref = retval_ptr = Z_INDIRECT_P(retval_ptr); } + ZVAL_DEREF(retval_ptr); + } else if (IS_CV == IS_CV) { + ZVAL_DEREF(retval_ptr); } - ZEND_VM_NEXT_OPCODE(); - } - SAVE_OPLINE(); - if (IS_CV == IS_CONST) { - op1_str = Z_STR_P(op1); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - op1_str = zend_string_copy(Z_STR_P(op1)); - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - op1_str = zval_get_string_func(op1); - } - if (IS_CV == IS_CONST) { - op2_str = Z_STR_P(op2); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - op2_str = zend_string_copy(Z_STR_P(op2)); - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + ZEND_VM_NEXT_OPCODE(); } - op2_str = zval_get_string_func(op2); - } - do { - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { - GC_ADDREF(op2_str); - } - } - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - zend_string_release_ex(op1_str, 0); - break; + + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { + SAVE_OPLINE(); + retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { + ZEND_VM_NEXT_OPCODE(); } } - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { - GC_ADDREF(op1_str); - } + + zend_reference *ref = NULL; + if (UNEXPECTED(retval_ref != retval_ptr)) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + ref = Z_REF_P(retval_ref); + } else { + /* A cast might happen - unwrap the reference if this is a by-value return */ + if (Z_REFCOUNT_P(retval_ref) == 1) { + ZVAL_UNREF(retval_ref); + } else { + Z_DELREF_P(retval_ref); + ZVAL_COPY(retval_ref, retval_ptr); } - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - zend_string_release_ex(op2_str, 0); - break; + retval_ptr = retval_ref; } } - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CV != IS_CONST) { - zend_string_release_ex(op1_str, 0); + SAVE_OPLINE(); + if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, 1, 0))) { + zend_verify_return_error(EX(func), retval_ptr); + HANDLE_EXCEPTION(); } - if (IS_CV != IS_CONST) { - zend_string_release_ex(op2_str, 0); + ZEND_VM_NEXT_OPCODE(); +#endif + } +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varptr, *arg; + + if (IS_UNUSED == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + uint32_t arg_num; + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + + + HANDLE_EXCEPTION(); } - } while (0); + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + } + varptr = EX_VAR(opline->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(arg); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + if (IS_CV == IS_CV) { + ZVAL_COPY_DEREF(arg, varptr); + } else /* if (IS_CV == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(varptr))) { + zend_refcounted *ref = Z_COUNTED_P(varptr); + varptr = Z_REFVAL_P(varptr); + ZVAL_COPY_VALUE(arg, varptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(arg)) { + Z_ADDREF_P(arg); + } + } else { + ZVAL_COPY_VALUE(arg, varptr); + } + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_REF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zval *object; - zend_function *fbc; - zend_class_entry *called_scope; - zend_object *obj; - zend_execute_data *call; - uint32_t call_info; + zval *varptr, *arg; SAVE_OPLINE(); + if (IS_UNUSED == IS_CONST) { + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + uint32_t arg_num; + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { - object = EX_VAR(opline->op1.var); - if (IS_CV != IS_CONST) { - function_name = EX_VAR(opline->op2.var); + HANDLE_EXCEPTION(); + } + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); } - if (IS_CV != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { + varptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(varptr)) { + Z_ADDREF_P(varptr); + } else { + ZVAL_MAKE_REF_EX(varptr, 2); + } + ZVAL_REF(arg, Z_REF_P(varptr)); - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Method name must be a string"); + ZEND_VM_NEXT_OPCODE(); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varptr, *arg; + uint32_t arg_num; + if (IS_UNUSED == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { HANDLE_EXCEPTION(); - } while (0); - } - - if (IS_CV == IS_UNUSED) { - obj = Z_OBJ_P(object); + } } else { - do { - if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - } else { - if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - zend_reference *ref = Z_REF_P(object); - - object = &ref->val; - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - if (IS_CV & IS_VAR) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_ADDREF_P(object); - } - } - break; - } - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - object = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CV != IS_CONST) { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + arg_num = opline->op2.num; + } + if (EXPECTED(0)) { + if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_var_by_ref; + } + } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { +send_var_by_ref: + varptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(varptr)) { + Z_ADDREF_P(varptr); + } else { + ZVAL_MAKE_REF_EX(varptr, 2); + } + ZVAL_REF(arg, Z_REF_P(varptr)); - } - HANDLE_EXCEPTION(); - } - } - if (IS_CV == IS_CONST) { - function_name = EX_VAR(opline->op2.var); - } - zend_invalid_method_call(object, function_name); + ZEND_VM_NEXT_OPCODE(); + } + varptr = EX_VAR(opline->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(arg); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + if (IS_CV == IS_CV) { + ZVAL_COPY_DEREF(arg, varptr); + } else /* if (IS_CV == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(varptr))) { + zend_refcounted *ref = Z_COUNTED_P(varptr); - HANDLE_EXCEPTION(); + varptr = Z_REFVAL_P(varptr); + ZVAL_COPY_VALUE(arg, varptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(arg)) { + Z_ADDREF_P(arg); } - } while (0); + } else { + ZVAL_COPY_VALUE(arg, varptr); + } } - called_scope = obj->ce; - - if (IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else { - zend_object *orig_obj = obj; + ZEND_VM_NEXT_OPCODE(); +} - if (IS_CV == IS_CONST) { - function_name = EX_VAR(opline->op2.var); - } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SPEC_CV_UNUSED_QUICK_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varptr, *arg; + uint32_t arg_num; - /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); - } + if (IS_UNUSED == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); - } HANDLE_EXCEPTION(); } - if (IS_CV == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); - } - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ - if (GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); - } + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + arg_num = opline->op2.num; + } + + if (EXPECTED(1)) { + if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_var_by_ref; } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); + } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { +send_var_by_ref: + varptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(varptr)) { + Z_ADDREF_P(varptr); + } else { + ZVAL_MAKE_REF_EX(varptr, 2); } - } + ZVAL_REF(arg, Z_REF_P(varptr)); - if (IS_CV != IS_CONST) { + ZEND_VM_NEXT_OPCODE(); + } + varptr = EX_VAR(opline->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(varptr) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(arg); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { - zend_objects_store_del(obj); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + if (IS_CV == IS_CV) { + ZVAL_COPY_DEREF(arg, varptr); + } else /* if (IS_CV == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(varptr))) { + zend_refcounted *ref = Z_COUNTED_P(varptr); + + varptr = Z_REFVAL_P(varptr); + ZVAL_COPY_VALUE(arg, varptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(arg)) { + Z_ADDREF_P(arg); } + } else { + ZVAL_COPY_VALUE(arg, varptr); } - /* call static method */ - obj = (zend_object*)called_scope; - call_info = ZEND_CALL_NESTED_FUNCTION; - } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { - if (IS_CV == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ - } - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, obj); - call->prev_execute_data = EX(call); - EX(call) = call; - ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *expr_ptr, new_expr; @@ -55933,15 +49570,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELE } } - if (IS_CV != IS_UNUSED) { - zval *offset = EX_VAR(opline->op2.var); + if (IS_UNUSED != IS_UNUSED) { + zval *offset = NULL; zend_string *str; zend_ulong hval; add_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); - if (IS_CV != IS_CONST) { + if (IS_UNUSED != IS_CONST) { if (ZEND_HANDLE_NUMERIC(str, hval)) { goto num_index; } @@ -55952,7 +49589,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELE hval = Z_LVAL_P(offset); num_index: zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { offset = Z_REFVAL_P(offset); goto add_again; } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { @@ -55985,7 +49622,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELE zend_use_resource_as_offset(offset); hval = Z_RES_HANDLE_P(offset); goto num_index; - } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); str = ZSTR_EMPTY_ALLOC(); goto str_index; @@ -55997,353 +49634,230 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELE } else { if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { - zend_cannot_add_element(); - zval_ptr_dtor_nogc(expr_ptr); - } - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zval *array; - uint32_t size; - USE_OPLINE - - SAVE_OPLINE(); - array = EX_VAR(opline->result.var); - if (IS_CV != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); - } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZVAL_ARR(array, zend_new_array(0)); - ZEND_VM_NEXT_OPCODE(); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - zval *offset; - zend_ulong hval; - zend_string *key; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - offset = EX_VAR(opline->op2.var); - - do { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; - -unset_dim_array: - SEPARATE_ARRAY(container); - ht = Z_ARRVAL_P(container); -offset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - key = Z_STR_P(offset); - if (IS_CV != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(key, hval)) { - goto num_index_dim; - } - } -str_index_dim: - ZEND_ASSERT(ht != &EG(symbol_table)); - zend_hash_del(ht, key); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_dim: - zend_hash_index_del(ht, hval); - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto offset_again; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - /* The array may be destroyed while throwing a warning in case the float is not representable as an int. - * Temporarily increase the refcount to detect this situation. */ - GC_TRY_ADDREF(ht); - hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - break; - } - if (EG(exception)) { - break; - } - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_NULL) { - key = ZSTR_EMPTY_ALLOC(); - goto str_index_dim; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index_dim; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - zend_use_resource_as_offset(offset); - hval = Z_RES_HANDLE_P(offset); - goto num_index_dim; - } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - key = ZSTR_EMPTY_ALLOC(); - goto str_index_dim; - } else { - zend_illegal_array_offset_unset(offset); - } - break; - } else if (Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto unset_dim_array; - } - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - container = ZVAL_UNDEFINED_OP1(); - } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { - offset = ZVAL_UNDEFINED_OP2(); - } - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset); - } else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { - zend_throw_error(NULL, "Cannot unset string offsets"); - } else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) { - zend_throw_error(NULL, "Cannot unset offset in a non-array variable"); - } else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) { - zend_false_to_array_deprecated(); - } - } while (0); - - - - + zend_cannot_add_element(); + zval_ptr_dtor_nogc(expr_ptr); + } + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zval *array; + uint32_t size; USE_OPLINE - zval *container; - zval *offset; - zend_string *name, *tmp_name; SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - - do { - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - if (Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (Z_TYPE_P(container) != IS_OBJECT) { - if (IS_CV == IS_CV - && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - break; - } - } else { - break; - } - } - if (IS_CV == IS_CONST) { - name = Z_STR_P(offset); - } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - break; - } - } - Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + array = EX_VAR(opline->result.var); + if (IS_CV != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); } - } while (0); - + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_ARR(array, zend_new_array(0)); + ZEND_VM_NEXT_OPCODE(); + } +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_CV_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *var = EX_VAR(opline->op1.var); + if (Z_REFCOUNTED_P(var)) { + zend_refcounted *garbage = Z_COUNTED_P(var); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZVAL_UNDEF(var); + SAVE_OPLINE(); + GC_DTOR(garbage); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZVAL_UNDEF(var); + } + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - bool result; - zend_ulong hval; - zval *offset; + zval *varname; + zend_string *name, *tmp_name; + HashTable *target_symbol_table; SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - offset = EX_VAR(opline->op2.var); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; - zval *value; - zend_string *str; + varname = EX_VAR(opline->op1.var); -isset_dim_obj_array: - ht = Z_ARRVAL_P(container); -isset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_CV != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index_prop; - } - } - value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_prop: - value = zend_hash_index_find(ht, hval); - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { - offset = Z_REFVAL_P(offset); - goto isset_again; - } else { - value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); - if (UNEXPECTED(EG(exception))) { - result = 0; - goto isset_dim_obj_exit; - } + if (IS_CV == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = ZVAL_UNDEFINED_OP1(); } - - if (!(opline->extended_value & ZEND_ISEMPTY)) { - /* > IS_NULL means not IS_UNDEF and not IS_NULL */ - result = value != NULL && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - - if (IS_CV & (IS_CONST|IS_CV)) { - /* avoid exception check */ + name = zval_try_get_tmp_string(varname, &tmp_name); + if (UNEXPECTED(!name)) { - ZEND_VM_SMART_BRANCH(result, 0); - } - } else { - result = (value == NULL || !i_zend_is_true(value)); - } - goto isset_dim_obj_exit; - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto isset_dim_obj_array; + HANDLE_EXCEPTION(); } } - if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - if (!(opline->extended_value & ZEND_ISEMPTY)) { - result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); - } else { - result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); + target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); + zend_hash_del_ind(target_symbol_table, name); + + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } -isset_dim_obj_exit: + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */ +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + value = EX_VAR(opline->op1.var); + if (!(0)) { + if (Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL)) { + ZEND_VM_SMART_BRANCH_TRUE(); + } else { + ZEND_VM_SMART_BRANCH_FALSE(); + } + } else { + bool result; - ZEND_VM_SMART_BRANCH(result, 1); + SAVE_OPLINE(); + result = !i_zend_is_true(value); + ZEND_VM_SMART_BRANCH(result, 1); + } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - int result; - zval *offset; - zend_string *name, *tmp_name; - - SAVE_OPLINE(); - container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + zval *value; - if (IS_CV == IS_CONST || - (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } + value = EX_VAR(opline->op1.var); + if (!(1)) { + if (Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL)) { + ZEND_VM_SMART_BRANCH_TRUE(); } else { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; + ZEND_VM_SMART_BRANCH_FALSE(); } + } else { + bool result; + + SAVE_OPLINE(); + result = !i_zend_is_true(value); + ZEND_VM_SMART_BRANCH(result, 1); } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + bool result; + zval *varname; + zend_string *name, *tmp_name; + HashTable *target_symbol_table; + SAVE_OPLINE(); + varname = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); if (IS_CV == IS_CONST) { - name = Z_STR_P(offset); + name = Z_STR_P(varname); } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - result = 0; - goto isset_object_finish; - } + name = zval_get_tmp_string(varname, &tmp_name); } - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); + value = zend_hash_find_ex(target_symbol_table, name, IS_CV == IS_CONST); if (IS_CV != IS_CONST) { zend_tmp_string_release(tmp_name); } -isset_object_finish: - - + if (!value) { + result = (opline->extended_value & ZEND_ISEMPTY); + } else { + if (Z_TYPE_P(value) == IS_INDIRECT) { + value = Z_INDIRECT_P(value); + } + if (!(opline->extended_value & ZEND_ISEMPTY)) { + if (Z_ISREF_P(value)) { + value = Z_REFVAL_P(value); + } + result = Z_TYPE_P(value) > IS_NULL; + } else { + result = !i_zend_is_true(value); + } + } - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_SMART_BRANCH(result, true); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INSTANCEOF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - - zval *key, *subject; - HashTable *ht; + zval *expr; bool result; SAVE_OPLINE(); + expr = EX_VAR(opline->op1.var); - key = EX_VAR(opline->op1.var); - subject = EX_VAR(opline->op2.var); +try_instanceof: + if (Z_TYPE_P(expr) == IS_OBJECT) { + zend_class_entry *ce; - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { -array_key_exists_array: - ht = Z_ARRVAL_P(subject); - result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); - } else { - if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { - subject = Z_REFVAL_P(subject); - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { - goto array_key_exists_array; + if (IS_UNUSED == IS_CONST) { + ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (EXPECTED(ce)) { + CACHE_PTR(opline->extended_value, ce); + } + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { + expr = Z_REFVAL_P(expr); + goto try_instanceof; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } - zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); result = 0; } - - ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -56430,9 +49944,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CV } /* Set the new yielded key */ - if (IS_CV != IS_UNUSED) { - zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if ((IS_CV & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + if (IS_UNUSED != IS_UNUSED) { + zval *key = NULL; + if ((IS_UNUSED & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { key = Z_REFVAL_P(key); } ZVAL_COPY(&generator->key, key); @@ -56458,8724 +49972,9579 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CV generator->send_target = NULL; } - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); + + ZEND_VM_RETURN(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CHECK_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1 = EX_VAR(opline->op1.var); + + if (UNEXPECTED(Z_TYPE_INFO_P(op1) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MAKE_REF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1 = EX_VAR(opline->op1.var); + + if (IS_CV == IS_CV) { + if (UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_NEW_EMPTY_REF(op1); + Z_SET_REFCOUNT_P(op1, 2); + ZVAL_NULL(Z_REFVAL_P(op1)); + ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); + } else { + if (Z_ISREF_P(op1)) { + Z_ADDREF_P(op1); + } else { + ZVAL_MAKE_REF_EX(op1, 2); + } + ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_INDIRECT)) { + op1 = Z_INDIRECT_P(op1); + if (EXPECTED(!Z_ISREF_P(op1))) { + ZVAL_MAKE_REF_EX(op1, 2); + } else { + GC_ADDREF(Z_REF_P(op1)); + } + ZVAL_REF(EX_VAR(opline->result.var), Z_REF_P(op1)); + } else { + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), op1); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1; + zend_long count; + + SAVE_OPLINE(); + op1 = EX_VAR(opline->op1.var); + + while (1) { + if (Z_TYPE_P(op1) == IS_ARRAY) { + count = zend_hash_num_elements(Z_ARRVAL_P(op1)); + break; + } else if (Z_TYPE_P(op1) == IS_OBJECT) { + zend_object *zobj = Z_OBJ_P(op1); + + /* first, we check if the handler is defined */ + if (zobj->handlers->count_elements) { + if (SUCCESS == zobj->handlers->count_elements(zobj, &count)) { + break; + } + if (UNEXPECTED(EG(exception))) { + count = 0; + break; + } + } + + /* if not and the object implements Countable we call its count() method */ + if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) { + zval retval; + + zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT)); + zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval); + count = zval_get_long(&retval); + zval_ptr_dtor(&retval); + break; + } + + /* If There's no handler and it doesn't implement Countable then emit a TypeError */ + } else if ((IS_CV & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + continue; + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + count = 0; + zend_type_error("%s(): Argument #1 ($value) must be of type Countable|array, %s given", opline->extended_value ? "sizeof" : "count", zend_zval_value_name(op1)); + break; + } + + ZVAL_LONG(EX_VAR(opline->result.var), count); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_COUNT_ARRAY_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_array *ht = Z_ARRVAL_P(EX_VAR(opline->op1.var)); + ZVAL_LONG(EX_VAR(opline->result.var), zend_hash_num_elements(ht)); + if (IS_CV & (IS_TMP_VAR|IS_VAR) && !(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + SAVE_OPLINE(); + zend_array_destroy(ht); + if (EG(exception)) { + HANDLE_EXCEPTION(); + } + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_CLASS_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (IS_CV == IS_UNUSED) { + SAVE_OPLINE(); + if (UNEXPECTED(!EX(func)->common.scope)) { + zend_throw_error(NULL, "get_class() without arguments must be called from within a class"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } else { + zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated"); + ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + ZEND_VM_NEXT_OPCODE(); + } + } else { + zval *op1; + + SAVE_OPLINE(); + op1 = EX_VAR(opline->op1.var); + while (1) { + if (Z_TYPE_P(op1) == IS_OBJECT) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); + } else if ((IS_CV & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + continue; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_type_error("get_class(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(op1)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + break; + } + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_GET_TYPE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1; + zend_string *type; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + type = zend_zval_get_legacy_type(op1); + if (EXPECTED(type)) { + ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type); + } else { + ZVAL_STRING(EX_VAR(opline->result.var), "unknown type"); + } + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varptr, *arg; + uint32_t arg_num = opline->op2.num; + + if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + ZEND_VM_TAIL_CALL(ZEND_SEND_REF_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + varptr = EX_VAR(opline->op1.var); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + + if (IS_CV == IS_CV) { + ZVAL_COPY(arg, varptr); + } else /* if (IS_CV == IS_VAR) */ { + ZVAL_COPY_VALUE(arg, varptr); + } + + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DIV_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + div_function(EX_VAR(opline->result.var), op1, op2); - ZEND_VM_RETURN(); + + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - /* This is declared below the specializations for MAY_BE_LONG/MAY_BE_DOUBLE so those will be used instead if possible. */ - /* This optimizes $x === SOME_CONST_EXPR and $x === $y for non-refs and non-undef, which can't throw. */ - /* (Infinite recursion when comparing arrays is an uncatchable fatal error) */ USE_OPLINE zval *op1, *op2; - bool result; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = fast_is_identical_function(op1, op2); - /* Free is a no-op for const/cv */ - ZEND_VM_SMART_BRANCH(result, 0); + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + pow_function(EX_VAR(opline->result.var), op1, op2); + + + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - bool result; op1 = EX_VAR(opline->op1.var); op2 = EX_VAR(opline->op2.var); - result = fast_is_identical_function(op1, op2); - /* Free is a no-op for const/cv */ - ZEND_VM_SMART_BRANCH(!result, 0); + + if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + + if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else if (IS_CV != IS_CONST && IS_CV != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { + zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = ZVAL_UNDEFINED_OP1(); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = ZVAL_UNDEFINED_OP2(); + } + concat_function(EX_VAR(opline->result.var), op1, op2); + + + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *op1, *op2; + bool result; SAVE_OPLINE(); - zend_error_noreturn(E_ERROR, "Invalid opcode %d/%d/%d.", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type); - ZEND_VM_NEXT_OPCODE(); /* Never reached */ -} + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + result = fast_is_identical_function(op1, op2); -#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) -# undef ZEND_VM_TAIL_CALL -# undef ZEND_VM_CONTINUE -# undef ZEND_VM_RETURN -# define ZEND_VM_TAIL_CALL(call) call; ZEND_VM_CONTINUE() -# define ZEND_VM_CONTINUE() HYBRID_NEXT() -# define ZEND_VM_RETURN() goto HYBRID_HALT_LABEL -#endif -#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL + ZEND_VM_SMART_BRANCH(result, 1); +} -# undef ZEND_VM_TAIL_CALL -# undef ZEND_VM_CONTINUE -# undef ZEND_VM_RETURN -# undef ZEND_VM_DISPATCH_TO_HELPER -# undef ZEND_VM_INTERRUPT +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; -# define ZEND_VM_TAIL_CALL(call) ZEND_MUSTTAIL return call -# define ZEND_VM_CONTINUE() ZEND_VM_TAIL_CALL(opline->handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)) -# define ZEND_VM_RETURN() opline = &call_halt_op; ZEND_VM_CONTINUE() -# define ZEND_VM_DISPATCH_TO_HELPER(call) \ - do { \ - opline = call; \ - ZEND_VM_TAIL_CALL(opline->handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); \ - } while (0) -# define ZEND_VM_DISPATCH_TO_LEAVE_HELPER(helper) opline = &call_leave_op; SAVE_OPLINE(); ZEND_VM_CONTINUE() -# define ZEND_VM_INTERRUPT() ZEND_VM_TAIL_CALL(zend_interrupt_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)) + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + result = fast_is_not_identical_function(op1, op2); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_HALT_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS); -static zend_never_inline const zend_op *ZEND_OPCODE_HANDLER_CCONV zend_leave_helper_SPEC_TAILCALL(zend_execute_data *ex, const zend_op *opline); -static const zend_op call_halt_op = { - .handler = ZEND_HALT_TAILCALL_HANDLER, -}; -static const zend_op call_leave_op = { - .handler = zend_leave_helper_SPEC_TAILCALL, -}; -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_sub_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_mul_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); -static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_mod_by_zero_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) + + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *op1, *op2; + double d1, d2; - SAVE_OPLINE(); - zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_mod_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_shift_left_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_shift_right_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_bw_or_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_bw_and_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_bw_xor_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_bw_not_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1); -static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_this_not_in_object_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *op1, *op2; + double d1, d2; - SAVE_OPLINE(); - zend_throw_error(NULL, "Using $this when not in object context"); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_undefined_function_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_EQUAL_SPEC_CV_CV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; + zval *op1, *op2; + double d1, d2; - SAVE_OPLINE(); - function_name = RT_CONSTANT(opline, opline->op2); - zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(function_name)); - HANDLE_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_STATIC_PROP_OP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - /* 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 */ - USE_OPLINE - zval *prop, *value; - zend_property_info *prop_info; - zend_reference *ref; - - SAVE_OPLINE(); + zval *op1, *op2; + double d1, d2; - prop = zend_fetch_static_property_address(&prop_info, (opline+1)->extended_value, BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(!prop)) { - UNDEF_RESULT(); - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - HANDLE_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} - if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK) - && UNEXPECTED(!zend_asymmetric_property_has_set_access(prop_info))) { - zend_asymmetric_visibility_property_modification_error(prop_info, "indirectly modify"); - UNDEF_RESULT(); - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - HANDLE_EXCEPTION(); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} - value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; - do { - if (UNEXPECTED(Z_ISREF_P(prop))) { - ref = Z_REF_P(prop); - prop = Z_REFVAL_P(prop); - if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { - zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); - break; + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CV == IS_CONST && IS_CV == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; } - - if (ZEND_TYPE_IS_SET(prop_info->type)) { - /* special case for typed properties */ - zend_binary_assign_op_typed_prop(prop_info, prop, value OPLINE_CC EXECUTE_DATA_CC); - } else { - zend_binary_op(prop, prop, value OPLINE_CC); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } } - } while (0); - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), prop); } - - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - /* assign_static_prop has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_STATIC_PROP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SPACESHIP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *prop; - zend_property_info *prop_info; + zval *op1, *op2; SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + compare_function(EX_VAR(opline->result.var), op1, op2); - prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(!prop)) { - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK) - && UNEXPECTED(!zend_asymmetric_property_has_set_access(prop_info))) { - zend_asymmetric_visibility_property_modification_error(prop_info, "indirectly modify"); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - zend_pre_incdec_property_zval(prop, - ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_STATIC_PROP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_BOOL_XOR_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *prop; - zend_property_info *prop_info; + zval *op1, *op2; SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + boolean_xor_function(EX_VAR(opline->result.var), op1, op2); - prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(!prop)) { - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK) - && UNEXPECTED(!zend_asymmetric_property_has_set_access(prop_info))) { - zend_asymmetric_visibility_property_modification_error(prop_info, "indirectly modify"); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - zend_post_incdec_property_zval(prop, - ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX int type); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_R_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R)); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_W_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W)); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_RW_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW)); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - ZEND_VM_TAIL_CALL(ZEND_FETCH_STATIC_PROP_W_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_STATIC_PROP_R_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET)); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_IS_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS)); -} - -static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot use temporary expression in write context"); - FREE_OP(opline->op2_type, opline->op2.var); - FREE_OP(opline->op1_type, opline->op1.var); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); -} - -static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot use [] for reading"); - FREE_OP(opline->op2_type, opline->op2.var); - FREE_OP(opline->op1_type, opline->op1.var); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *prop, *value; + zval *object; + zval *property; + zval *value; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; zend_property_info *prop_info; - zend_refcounted *garbage = NULL; + zend_object *zobj; + zend_string *name, *tmp_name; SAVE_OPLINE(); + object = EX_VAR(opline->op1.var); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(!prop)) { + do { + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_op_object; + } + if (IS_CV == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } +assign_op_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + UNDEF_RESULT(); + break; + } + } + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + zend_reference *ref; - value = RT_CONSTANT((opline+1), (opline+1)->op1); + do { + if (UNEXPECTED(Z_ISREF_P(zptr))) { + ref = Z_REF_P(zptr); + zptr = Z_REFVAL_P(zptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; + } + } - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC); + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + if (prop_info) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_binary_op(zptr, zptr, value OPLINE_CC); + } + } while (0); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), zptr); + } + } + } else { + zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); + } + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); - } else { - value = zend_assign_to_variable_ex(prop, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); - } + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - /* assign_static_prop has two opcodes! */ + + /* assign_obj has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *prop, *value; - zend_property_info *prop_info; - zend_refcounted *garbage = NULL; + zval *var_ptr; + zval *value, *container, *dim; + HashTable *ht; SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); - prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(!prop)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } else { - value = zend_assign_to_variable_ex(prop, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - } + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +assign_dim_op_array: + SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); +assign_dim_op_new_array: + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_UNUSED) { + var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); + if (UNEXPECTED(!var_ptr)) { + zend_cannot_add_element(); + goto assign_dim_op_ret_null; + } + } else { + if (IS_CV == IS_CONST) { + var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); + } else { + var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(!var_ptr)) { + goto assign_dim_op_ret_null; + } + } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); - if (garbage) { - GC_DTOR_NO_REF(garbage); - } + do { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; + } + } + zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); + } while (0); - /* assign_static_prop has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); + } + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + } else { + if (EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto assign_dim_op_array; + } + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *prop, *value; - zend_property_info *prop_info; - zend_refcounted *garbage = NULL; + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(container); - SAVE_OPLINE(); + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); + } else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) { + uint8_t old_type; - prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(!prop)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + ht = zend_new_array(8); + old_type = Z_TYPE_P(container); + ZVAL_ARR(container, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_op_ret_null; + } + } + goto assign_dim_op_new_array; + } else { + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); +assign_dim_op_ret_null: + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } else { - value = zend_assign_to_variable_ex(prop, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - /* assign_static_prop has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OP_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *prop, *value; - zend_property_info *prop_info; - zend_refcounted *garbage = NULL; + zval *var_ptr; + zval *value; SAVE_OPLINE(); + value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + var_ptr = _get_zval_ptr_cv_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC); - prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(!prop)) { - + do { + if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_REFERENCE)) { + zend_reference *ref = Z_REF_P(var_ptr); + var_ptr = Z_REFVAL_P(var_ptr); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; + } + } + zend_binary_op(var_ptr, var_ptr, value OPLINE_CC); + } while (0); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - - if (ZEND_TYPE_IS_SET(prop_info->type)) { - value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC); - - - } else { - value = zend_assign_to_variable_ex(prop, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - /* assign_static_prop has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_STATIC_PROP_REF_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_PRE_INC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *prop, *value_ptr; + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; zend_property_info *prop_info; - zend_refcounted *garbage = NULL; + zend_object *zobj; + zend_string *name, *tmp_name; SAVE_OPLINE(); + object = EX_VAR(opline->op1.var); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - prop = zend_fetch_static_property_address(&prop_info, opline->extended_value & ~ZEND_RETURNS_FUNCTION, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC); - if (UNEXPECTED(!prop)) { - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - - if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK) - && UNEXPECTED(!zend_asymmetric_property_has_set_access(prop_info))) { - zend_asymmetric_visibility_property_modification_error(prop_info, "indirectly modify"); - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - - value_ptr = get_zval_ptr_ptr((opline+1)->op1_type, (opline+1)->op1, BP_VAR_W); + do { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto pre_incdec_object; + } + if (IS_CV == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; + } - if ((opline+1)->op1_type == IS_VAR && (opline->extended_value & ZEND_RETURNS_FUNCTION) && UNEXPECTED(!Z_ISREF_P(value_ptr))) { - if (UNEXPECTED(!zend_wrong_assign_to_variable_reference(prop, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC))) { - prop = &EG(uninitialized_zval); +pre_incdec_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + UNDEF_RESULT(); + break; + } } - } else if (ZEND_TYPE_IS_SET(prop_info->type)) { - prop = zend_assign_to_typed_property_reference(prop_info, prop, value_ptr, &garbage EXECUTE_DATA_CC); - } else { - zend_assign_to_variable_reference(prop, value_ptr, &garbage); - } + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } else { + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); + zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); + } + } else { + zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); + } + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), prop); - } - if (garbage) { - GC_DTOR(garbage); - } - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - ZEND_VM_NEXT_OPCODE_EX(1, 2); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_leave_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_POST_INC_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zend_execute_data *old_execute_data; - uint32_t call_info = EX_CALL_INFO(); -#if ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL - /* zend_leave_helper may be called with opline=call_leave_op in TAILCALL VM */ - SAVE_OPLINE(); -#endif + USE_OPLINE + zval *object; + zval *property; + zval *zptr; + void *_cache_slot[3] = {0}; + void **cache_slot; + zend_property_info *prop_info; + zend_object *zobj; + zend_string *name, *tmp_name; - if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED|ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) == 0)) { - EG(current_execute_data) = EX(prev_execute_data); - i_free_compiled_variables(execute_data); + SAVE_OPLINE(); + object = EX_VAR(opline->op1.var); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); -#ifdef ZEND_PREFER_RELOAD - call_info = EX_CALL_INFO(); -#endif - if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { - OBJ_RELEASE(Z_OBJ(execute_data->This)); - } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { - OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); + do { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto post_incdec_object; + } + if (IS_CV == IS_CV + && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_throw_non_object_error(object, property OPLINE_CC EXECUTE_DATA_CC); + break; } - EG(vm_stack_top) = (zval*)execute_data; - execute_data = EX(prev_execute_data); - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - HANDLE_EXCEPTION_LEAVE(); +post_incdec_object: + /* here we are sure we are dealing with an object */ + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + name = Z_STR_P(property); + } else { + name = zval_try_get_tmp_string(property, &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; + } } - - LOAD_NEXT_OPLINE(); - ZEND_VM_LEAVE(); - } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) { - EG(current_execute_data) = EX(prev_execute_data); - i_free_compiled_variables(execute_data); - -#ifdef ZEND_PREFER_RELOAD - call_info = EX_CALL_INFO(); -#endif - if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { - zend_clean_and_cache_symbol_table(EX(symbol_table)); + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { + if (UNEXPECTED(Z_ISERROR_P(zptr))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } else { + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); + zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); + } + } else { + zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); } - - if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { - zend_free_extra_named_params(EX(extra_named_params)); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } + } while (0); - /* Free extra args before releasing the closure, - * as that may free the op_array. */ - zend_vm_stack_free_extra_args_ex(call_info, execute_data); - if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { - OBJ_RELEASE(Z_OBJ(execute_data->This)); - } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { - OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); - } - old_execute_data = execute_data; - execute_data = EX(prev_execute_data); - zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - HANDLE_EXCEPTION_LEAVE(); - } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - LOAD_NEXT_OPLINE(); - ZEND_VM_LEAVE(); - } else if (EXPECTED((call_info & ZEND_CALL_TOP) == 0)) { - if (EX(func)->op_array.last_var > 0) { - zend_detach_symbol_table(execute_data); - call_info |= ZEND_CALL_NEEDS_REATTACH; - } - zend_destroy_static_vars(&EX(func)->op_array); - destroy_op_array(&EX(func)->op_array); - efree_size(EX(func), sizeof(zend_op_array)); - old_execute_data = execute_data; - execute_data = EG(current_execute_data) = EX(prev_execute_data); - zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container, *dim, *value; - if (call_info & ZEND_CALL_NEEDS_REATTACH) { - if (EX(func)->op_array.last_var > 0) { - zend_attach_symbol_table(execute_data); + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + if (IS_CV & (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 = EX_VAR(opline->op2.var); + if (IS_CV != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R EXECUTE_DATA_CC); + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } else if (IS_CV == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; } else { - ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_NEEDS_REATTACH); - } - } - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - HANDLE_EXCEPTION_LEAVE(); - } - - LOAD_NEXT_OPLINE(); - ZEND_VM_LEAVE(); - } else { - if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) { - EG(current_execute_data) = EX(prev_execute_data); - i_free_compiled_variables(execute_data); -#ifdef ZEND_PREFER_RELOAD - call_info = EX_CALL_INFO(); -#endif - if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_HAS_EXTRA_NAMED_PARAMS))) { - if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { - zend_clean_and_cache_symbol_table(EX(symbol_table)); - } - zend_vm_stack_free_extra_args_ex(call_info, execute_data); - if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { - zend_free_extra_named_params(EX(extra_named_params)); - } - } - if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { - OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); - } - ZEND_VM_RETURN(); - } else /* if (call_kind == ZEND_CALL_TOP_CODE) */ { - zend_array *symbol_table = EX(symbol_table); - - if (EX(func)->op_array.last_var > 0) { - zend_detach_symbol_table(execute_data); - call_info |= ZEND_CALL_NEEDS_REATTACH; + goto fetch_dim_r_slow; } - if (call_info & ZEND_CALL_NEEDS_REATTACH) { - old_execute_data = EX(prev_execute_data); - while (old_execute_data) { - if (old_execute_data->func && (ZEND_CALL_INFO(old_execute_data) & ZEND_CALL_HAS_SYMBOL_TABLE)) { - if (old_execute_data->symbol_table == symbol_table) { - if (old_execute_data->func->op_array.last_var > 0) { - zend_attach_symbol_table(old_execute_data); - } else { - ZEND_ADD_CALL_FLAG(old_execute_data, ZEND_CALL_NEEDS_REATTACH); - } - } - break; - } - old_execute_data = old_execute_data->prev_execute_data; - } + } else { +fetch_dim_r_slow: + if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; } - EG(current_execute_data) = EX(prev_execute_data); - ZEND_VM_RETURN(); + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); } + } else { + zend_fetch_dimension_address_read_R(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC); } + + + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *container; - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op1), 0); + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + zend_fetch_dimension_address_W(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); + + + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_execute_data *call = EX(call); - zend_function *fbc = call->func; - zval *ret; - zval retval; + zval *container; SAVE_OPLINE(); - EX(call) = call->prev_execute_data; + container = EX_VAR(opline->op1.var); + zend_fetch_dimension_address_RW(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); - call->prev_execute_data = execute_data; - EG(current_execute_data) = call; -#if ZEND_DEBUG - bool should_throw = zend_internal_call_should_throw(fbc, call); -#endif + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - ret = 0 ? EX_VAR(opline->result.var) : &retval; - ZVAL_NULL(ret); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + /* 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, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); - fbc->internal_function.handler(call, ret); -#if ZEND_DEBUG - if (!EG(exception) && call->func) { - if (should_throw) { - zend_internal_call_arginfo_violation(call->func); - } - ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, ret)); - ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) - ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); - zend_verify_internal_func_info(call->func, ret); - } -#endif - ZEND_VM_FCALL_INTERRUPT_CHECK(call); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - EG(current_execute_data) = execute_data; - zend_vm_stack_free_args(call); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ +#if 0 + USE_OPLINE +#endif - uint32_t call_info = ZEND_CALL_INFO(call); - if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) { - if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { - zend_free_extra_named_params(call->extra_named_params); + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - zend_vm_stack_free_call_frame_ex(call_info, call); + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - EG(vm_stack_top) = (zval*)call; - } - - if (!0) { - i_zval_ptr_dtor(ret); - } - - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - HANDLE_EXCEPTION(); + if (IS_CV == IS_UNUSED) { + ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + if (IS_CV & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - - ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); - ZEND_VM_CONTINUE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_ICALL_SPEC_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_execute_data *call = EX(call); - zend_function *fbc = call->func; - zval *ret; - zval retval; + zval *container; SAVE_OPLINE(); - EX(call) = call->prev_execute_data; - - call->prev_execute_data = execute_data; - EG(current_execute_data) = call; + container = EX_VAR(opline->op1.var); + zend_fetch_dimension_address_UNSET(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); -#if ZEND_DEBUG - bool should_throw = zend_internal_call_should_throw(fbc, call); -#endif - ret = 1 ? EX_VAR(opline->result.var) : &retval; - ZVAL_NULL(ret); + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + void **cache_slot = NULL; - fbc->internal_function.handler(call, ret); + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + if (IS_CV & (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 ZEND_DEBUG - if (!EG(exception) && call->func) { - if (should_throw) { - zend_internal_call_arginfo_violation(call->func); - } - ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, ret)); - ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) - ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); - zend_verify_internal_func_info(call->func, ret); + if (IS_CV == IS_CONST || + (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if ((IS_CV & IS_CV) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_wrong_property_read(container, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; + } while (0); } -#endif + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; - ZEND_VM_FCALL_INTERRUPT_CHECK(call); + if (IS_CV == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); - EG(current_execute_data) = execute_data; - zend_vm_stack_free_args(call); + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - uint32_t call_info = ZEND_CALL_INFO(call); - if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) { - if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { - zend_free_extra_named_params(call->extra_named_params); - } - zend_vm_stack_free_call_frame_ex(call_info, call); - } else { - EG(vm_stack_top) = (zval*)call; - } + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_r_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { +fetch_obj_r_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + prop_offset = prop_info->offset; + goto fetch_obj_r_simple; + } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { + zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; + ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); + ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); - if (!1) { - i_zval_ptr_dtor(ret); - } + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (IS_CV & IS_CV) { + GC_ADDREF(zobj); + } + if (IS_CV & (IS_CV|IS_VAR|IS_TMP_VAR)) { + call_info |= ZEND_CALL_RELEASE_THIS; + } + zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); + call->prev_execute_data = execute_data; + call->call = NULL; + call->return_value = EX_VAR(opline->result.var); + call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - HANDLE_EXCEPTION(); - } + execute_data = call; + EG(current_execute_data) = execute_data; + zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); - ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); - ZEND_VM_CONTINUE(); -} +#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) + opline = hook->op_array.opcodes; +#else + EX(opline) = hook->op_array.opcodes; +#endif + LOAD_OPLINE_EX(); -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_ICALL_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_execute_data *call = EX(call); - zend_function *fbc = call->func; - zval *ret; - zval retval; - SAVE_OPLINE(); - EX(call) = call->prev_execute_data; - call->prev_execute_data = execute_data; - EG(current_execute_data) = call; -#if ZEND_DEBUG - bool should_throw = zend_internal_call_should_throw(fbc, call); -#endif + ZEND_VM_ENTER_EX(); + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); - ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval; - ZVAL_NULL(ret); + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); - zend_observer_fcall_begin_specialized(call, false); - fbc->internal_function.handler(call, ret); + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } + } + } + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + } else { + name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; + } + } #if ZEND_DEBUG - if (!EG(exception) && call->func) { - if (should_throw) { - zend_internal_call_arginfo_violation(call->func); + /* For non-standard object handlers, verify a declared property type in debug builds. + * Fetch prop_info before calling read_property(), as it may deallocate the object. */ + zend_property_info *prop_info = NULL; + if (zobj->handlers->read_property != zend_std_read_property) { + prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); + } +#endif + retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO + && ZEND_TYPE_IS_SET(prop_info->type)) { + ZVAL_OPT_DEREF(retval); + zend_verify_property_type(prop_info, retval, /* strict */ true); } - ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, ret)); - ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) - ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); - zend_verify_internal_func_info(call->func, ret); - } #endif - zend_observer_fcall_end(call, EG(exception) ? NULL : ret); - ZEND_VM_FCALL_INTERRUPT_CHECK(call); - EG(current_execute_data) = execute_data; - zend_vm_stack_free_args(call); - - uint32_t call_info = ZEND_CALL_INFO(call); - if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) { - if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { - zend_free_extra_named_params(call->extra_named_params); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } - zend_vm_stack_free_call_frame_ex(call_info, call); - } else { - EG(vm_stack_top) = (zval*)call; - } - - if (!RETURN_VALUE_USED(opline)) { - i_zval_ptr_dtor(ret); - } - - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - HANDLE_EXCEPTION(); - } - - ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); - ZEND_VM_CONTINUE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_UCALL_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_execute_data *call = EX(call); - zend_function *fbc = call->func; - zval *ret; - - SAVE_OPLINE(); - EX(call) = call->prev_execute_data; - ret = NULL; - if (0) { - ret = EX_VAR(opline->result.var); - } + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_r_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } + } while (0); - call->prev_execute_data = execute_data; - execute_data = call; - i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); - LOAD_OPLINE_EX(); +fetch_obj_r_finish: - ZEND_VM_ENTER_EX(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_UCALL_SPEC_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_execute_data *call = EX(call); - zend_function *fbc = call->func; - zval *ret; + zval *property, *container, *result; SAVE_OPLINE(); - EX(call) = call->prev_execute_data; - - ret = NULL; - if (1) { - ret = EX_VAR(opline->result.var); - } - - call->prev_execute_data = execute_data; - execute_data = call; - i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); - LOAD_OPLINE_EX(); - + container = EX_VAR(opline->op1.var); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + zend_fetch_property_address( + result, container, IS_CV, property, IS_CV, + ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); - ZEND_VM_ENTER_EX(); + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_UCALL_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_execute_data *call = EX(call); - zend_function *fbc = call->func; - zval *ret; + zval *property, *container, *result; SAVE_OPLINE(); - EX(call) = call->prev_execute_data; - - ret = NULL; - if (RETURN_VALUE_USED(opline)) { - ret = EX_VAR(opline->result.var); - } + container = EX_VAR(opline->op1.var); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - call->prev_execute_data = execute_data; - execute_data = call; - i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); - LOAD_OPLINE_EX(); - SAVE_OPLINE(); - zend_observer_fcall_begin_specialized(execute_data, false); - ZEND_VM_ENTER_EX(); + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_execute_data *call = EX(call); - zend_function *fbc = call->func; - zval *ret; - zval retval; + zval *container; + void **cache_slot = NULL; SAVE_OPLINE(); - EX(call) = call->prev_execute_data; - - const uint32_t no_discard = 0 ? 0 : ZEND_ACC_NODISCARD; + container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ - if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) { - if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) { - zend_deprecated_function(fbc); - } - if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) { - zend_nodiscard_function(fbc); - } - if (UNEXPECTED(EG(exception) != NULL)) { - UNDEF_RESULT(); - if (!0) { - ret = &retval; - ZVAL_UNDEF(ret); + if (IS_CV == IS_CONST || + (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } } - goto fcall_by_name_end; - } + if (IS_CV == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + } + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; + } while (0); } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { - ret = NULL; - if (0) { - ret = EX_VAR(opline->result.var); - } + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; - call->prev_execute_data = execute_data; - execute_data = call; - i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); - LOAD_OPLINE_EX(); + if (IS_CV == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value); + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_is_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { +fetch_obj_is_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + goto fetch_obj_is_simple; + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); - ZEND_VM_ENTER_EX(); - } else { - ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); - if (0) { - ret = NULL; + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || (IS_CV & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } + } + } + } + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + } else { + name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; + } } - call->prev_execute_data = execute_data; - EG(current_execute_data) = call; - -#if ZEND_DEBUG - bool should_throw = zend_internal_call_should_throw(fbc, call); -#endif - - ret = 0 ? EX_VAR(opline->result.var) : &retval; - ZVAL_NULL(ret); - + retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - fbc->internal_function.handler(call, ret); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } -#if ZEND_DEBUG - if (!EG(exception) && call->func) { - if (should_throw) { - zend_internal_call_arginfo_violation(call->func); - } - ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, ret)); - ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) - ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); - zend_verify_internal_func_info(call->func, ret); + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_is_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); } -#endif + } while (0); +fetch_obj_is_finish: - ZEND_VM_FCALL_INTERRUPT_CHECK(call); - EG(current_execute_data) = execute_data; - goto fcall_by_name_end; - } - if (0) { -fcall_by_name_end: + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - zend_vm_stack_free_args(call); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ +#if 0 + USE_OPLINE +#endif - uint32_t call_info = ZEND_CALL_INFO(call); - if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) { - if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { - zend_free_extra_named_params(call->extra_named_params); - } - zend_vm_stack_free_call_frame_ex(call_info, call); - } else { - EG(vm_stack_top) = (zval*)call; + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + /* Behave like FETCH_OBJ_W */ + if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - - if (!0) { - i_zval_ptr_dtor(ret); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if (IS_CV == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - HANDLE_EXCEPTION(); - } - ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); - ZEND_VM_CONTINUE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_execute_data *call = EX(call); - zend_function *fbc = call->func; - zval *ret; - zval retval; + zval *container, *property, *result; SAVE_OPLINE(); - EX(call) = call->prev_execute_data; + container = EX_VAR(opline->op1.var); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + result = EX_VAR(opline->result.var); + zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); - const uint32_t no_discard = 1 ? 0 : ZEND_ACC_NODISCARD; - if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) { - if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) { - zend_deprecated_function(fbc); - } - if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) { - zend_nodiscard_function(fbc); - } - if (UNEXPECTED(EG(exception) != NULL)) { - UNDEF_RESULT(); - if (!1) { - ret = &retval; - ZVAL_UNDEF(ret); - } - goto fcall_by_name_end; - } + if (IS_CV == IS_VAR) { + FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { - ret = NULL; - if (1) { - ret = EX_VAR(opline->result.var); - } - - call->prev_execute_data = execute_data; - execute_data = call; - i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); - LOAD_OPLINE_EX(); - - - - - ZEND_VM_ENTER_EX(); - } else { - ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); - if (0) { - ret = NULL; - } - - call->prev_execute_data = execute_data; - EG(current_execute_data) = call; - -#if ZEND_DEBUG - bool should_throw = zend_internal_call_should_throw(fbc, call); -#endif - - ret = 1 ? EX_VAR(opline->result.var) : &retval; - ZVAL_NULL(ret); - +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; - fbc->internal_function.handler(call, ret); + SAVE_OPLINE(); + object = EX_VAR(opline->op1.var); + value = RT_CONSTANT((opline+1), (opline+1)->op1); -#if ZEND_DEBUG - if (!EG(exception) && call->func) { - if (should_throw) { - zend_internal_call_arginfo_violation(call->func); - } - ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, ret)); - ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) - ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); - zend_verify_internal_func_info(call->func, ret); + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; } -#endif - - - ZEND_VM_FCALL_INTERRUPT_CHECK(call); - - EG(current_execute_data) = execute_data; - - goto fcall_by_name_end; + zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; } - if (0) { -fcall_by_name_end: +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - zend_vm_stack_free_args(call); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - uint32_t call_info = ZEND_CALL_INFO(call); - if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) { - if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { - zend_free_extra_named_params(call->extra_named_params); +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } + + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CONST != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CONST == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CONST == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ } - zend_vm_stack_free_call_frame_ex(call_info, call); - } else { - EG(vm_stack_top) = (zval*)call; - } - - if (!1) { - i_zval_ptr_dtor(ret); } - } - - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - HANDLE_EXCEPTION(); - } - ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); - ZEND_VM_CONTINUE(); -} - -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_execute_data *call = EX(call); - zend_function *fbc = call->func; - zval *ret; - zval retval; - - SAVE_OPLINE(); - EX(call) = call->prev_execute_data; + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + } else { + name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { - const uint32_t no_discard = RETURN_VALUE_USED(opline) ? 0 : ZEND_ACC_NODISCARD; - if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) { - if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) { - zend_deprecated_function(fbc); - } - if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) { - zend_nodiscard_function(fbc); - } - if (UNEXPECTED(EG(exception) != NULL)) { UNDEF_RESULT(); - if (!RETURN_VALUE_USED(opline)) { - ret = &retval; - ZVAL_UNDEF(ret); - } - goto fcall_by_name_end; + goto exit_assign_obj; } } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { - ret = NULL; - if (RETURN_VALUE_USED(opline)) { - ret = EX_VAR(opline->result.var); - } - - call->prev_execute_data = execute_data; - execute_data = call; - i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); - LOAD_OPLINE_EX(); - SAVE_OPLINE(); - zend_observer_fcall_begin_specialized(execute_data, false); - - ZEND_VM_ENTER_EX(); - } else { - ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); - if (1) { - ret = NULL; - } - - call->prev_execute_data = execute_data; - EG(current_execute_data) = call; - -#if ZEND_DEBUG - bool should_throw = zend_internal_call_should_throw(fbc, call); -#endif + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_DEREF(value); + } - ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval; - ZVAL_NULL(ret); + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - zend_observer_fcall_begin_specialized(call, false); - fbc->internal_function.handler(call, ret); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } -#if ZEND_DEBUG - if (!EG(exception) && call->func) { - if (should_throw) { - zend_internal_call_arginfo_violation(call->func); - } - ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, ret)); - ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) - ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); - zend_verify_internal_func_info(call->func, ret); - } -#endif - zend_observer_fcall_end(call, EG(exception) ? NULL : ret); - ZEND_VM_FCALL_INTERRUPT_CHECK(call); +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } - EG(current_execute_data) = execute_data; - goto fcall_by_name_end; +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); } - if (0) { -fcall_by_name_end: - - zend_vm_stack_free_args(call); - uint32_t call_info = ZEND_CALL_INFO(call); - if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) { - if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { - zend_free_extra_named_params(call->extra_named_params); - } - zend_vm_stack_free_call_frame_ex(call_info, call); - } else { - EG(vm_stack_top) = (zval*)call; - } - if (!RETURN_VALUE_USED(opline)) { - i_zval_ptr_dtor(ret); - } - } - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - HANDLE_EXCEPTION(); - } - ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); - ZEND_VM_CONTINUE(); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_execute_data *call = EX(call); - zend_function *fbc = call->func; - zval *ret; - zval retval; + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - EX(call) = call->prev_execute_data; - - const uint32_t no_discard = 0 ? 0 : ZEND_ACC_NODISCARD; + object = EX_VAR(opline->op1.var); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) { - if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) { - zend_deprecated_function(fbc); - } - if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) { - zend_nodiscard_function(fbc); - } - if (UNEXPECTED(EG(exception) != NULL)) { - if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) { - OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func)); - } - UNDEF_RESULT(); - if (!0) { - ret = &retval; - ZVAL_UNDEF(ret); - } - goto fcall_end; + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; } + zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { - ret = NULL; - if (0) { - ret = EX_VAR(opline->result.var); - } - - call->prev_execute_data = execute_data; - execute_data = call; - i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC); - - if (EXPECTED(zend_execute_ex == execute_ex)) { - LOAD_OPLINE_EX(); - - - +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - ZEND_VM_ENTER_EX(); - } else { - SAVE_OPLINE_EX(); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } - execute_data = EX(prev_execute_data); - LOAD_OPLINE(); - ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); - zend_execute_ex(call); + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_TMP_VAR != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_TMP_VAR == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_TMP_VAR == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ + } } + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); } else { - ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); - if (0) { - ret = NULL; - } - - call->prev_execute_data = execute_data; - EG(current_execute_data) = call; - -#if ZEND_DEBUG - bool should_throw = zend_internal_call_should_throw(fbc, call); -#endif - - ret = 0 ? EX_VAR(opline->result.var) : &retval; - ZVAL_NULL(ret); - - - if (!zend_execute_internal) { - /* saves one function call if zend_execute_internal is not used */ - fbc->internal_function.handler(call, ret); - } else { - zend_execute_internal(call, ret); - } - -#if ZEND_DEBUG - if (!EG(exception) && call->func && !(call->func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE)) { - if (should_throw) { - zend_internal_call_arginfo_violation(call->func); - } - ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, ret)); - ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) - ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); - zend_verify_internal_func_info(call->func, ret); + name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + goto exit_assign_obj; } -#endif - + } - ZEND_VM_FCALL_INTERRUPT_CHECK(call); + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_DEREF(value); + } - EG(current_execute_data) = execute_data; + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - goto fcall_end; + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } - if (0) { -fcall_end: +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); + } - zend_vm_stack_free_args(call); - if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { - zend_free_extra_named_params(call->extra_named_params); - } - if (!0) { - i_zval_ptr_dtor(ret); - } - } - if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) { - OBJ_RELEASE(Z_OBJ(call->This)); - } - zend_vm_stack_free_call_frame(call); - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - HANDLE_EXCEPTION(); - } - ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); - ZEND_VM_CONTINUE(); + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_SPEC_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_execute_data *call = EX(call); - zend_function *fbc = call->func; - zval *ret; - zval retval; + zval *object, *value, tmp; + zend_object *zobj; + zend_string *name, *tmp_name; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - EX(call) = call->prev_execute_data; - - const uint32_t no_discard = 1 ? 0 : ZEND_ACC_NODISCARD; + object = EX_VAR(opline->op1.var); + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) { - if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) { - zend_deprecated_function(fbc); - } - if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) { - zend_nodiscard_function(fbc); - } - if (UNEXPECTED(EG(exception) != NULL)) { - if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) { - OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func)); - } - UNDEF_RESULT(); - if (!1) { - ret = &retval; - ZVAL_UNDEF(ret); - } - goto fcall_end; + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { + if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { + object = Z_REFVAL_P(object); + goto assign_object; } + zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { - ret = NULL; - if (1) { - ret = EX_VAR(opline->result.var); - } - - call->prev_execute_data = execute_data; - execute_data = call; - i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC); - - if (EXPECTED(zend_execute_ex == execute_ex)) { - LOAD_OPLINE_EX(); - - - +assign_object: + zobj = Z_OBJ_P(object); + if (IS_CV == IS_CONST) { + if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { + void **cache_slot = CACHE_ADDR(opline->extended_value); + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + zval *property_val; + zend_property_info *prop_info; - ZEND_VM_ENTER_EX(); - } else { - SAVE_OPLINE_EX(); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { + prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); +assign_obj_simple: + property_val = OBJ_PROP(zobj, prop_offset); + if (Z_TYPE_P(property_val) != IS_UNDEF) { + if (prop_info != NULL) { + value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); + goto free_and_exit_assign_obj; + } else { +fast_assign_obj: + value = zend_assign_to_variable_ex(property_val, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } + } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (!zobj) { + value = &EG(uninitialized_zval); + goto free_and_exit_assign_obj; + } + } + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + rebuild_object_properties_internal(zobj); + } + if (EXPECTED(zobj->properties != NULL)) { + if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(zobj->properties); + } + zobj->properties = zend_array_dup(zobj->properties); + } + property_val = zend_hash_find_known_hash(zobj->properties, name); + if (property_val) { + goto fast_assign_obj; + } + } - execute_data = EX(prev_execute_data); - LOAD_OPLINE(); - ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); - zend_execute_ex(call); + if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } else if (IS_CV != IS_TMP_VAR) { + if (Z_ISREF_P(value)) { + if (IS_CV == IS_VAR) { + zend_reference *ref = Z_REF_P(value); + if (GC_DELREF(ref) == 0) { + ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); + efree_size(ref, sizeof(zend_reference)); + value = &tmp; + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else { + value = Z_REFVAL_P(value); + Z_TRY_ADDREF_P(value); + } + } else if (IS_CV == IS_CV) { + Z_TRY_ADDREF_P(value); + } + } + zend_hash_add_new(zobj->properties, name, value); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + goto exit_assign_obj; + } + } else { + ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { + prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + if (!ZEND_TYPE_IS_SET(prop_info->type)) { + prop_info = NULL; + } + goto assign_obj_simple; + } + /* Fall through to write_property for hooks. */ + } } + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); } else { - ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); - if (0) { - ret = NULL; - } - - call->prev_execute_data = execute_data; - EG(current_execute_data) = call; - -#if ZEND_DEBUG - bool should_throw = zend_internal_call_should_throw(fbc, call); -#endif - - ret = 1 ? EX_VAR(opline->result.var) : &retval; - ZVAL_NULL(ret); - + name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { - if (!zend_execute_internal) { - /* saves one function call if zend_execute_internal is not used */ - fbc->internal_function.handler(call, ret); - } else { - zend_execute_internal(call, ret); - } -#if ZEND_DEBUG - if (!EG(exception) && call->func && !(call->func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE)) { - if (should_throw) { - zend_internal_call_arginfo_violation(call->func); - } - ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, ret)); - ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) - ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); - zend_verify_internal_func_info(call->func, ret); + UNDEF_RESULT(); + goto exit_assign_obj; } -#endif - + } - ZEND_VM_FCALL_INTERRUPT_CHECK(call); + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_DEREF(value); + } - EG(current_execute_data) = execute_data; + value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - goto fcall_end; + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); } - if (0) { -fcall_end: +free_and_exit_assign_obj: + if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } - zend_vm_stack_free_args(call); - if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { - zend_free_extra_named_params(call->extra_named_params); - } - if (!1) { - i_zval_ptr_dtor(ret); - } +exit_assign_obj: + if (garbage) { + GC_DTOR_NO_REF(garbage); } - if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) { - OBJ_RELEASE(Z_OBJ(call->This)); - } - zend_vm_stack_free_call_frame(call); - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - HANDLE_EXCEPTION(); - } - ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); - ZEND_VM_CONTINUE(); + + + /* assign_obj has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_execute_data *call = EX(call); - zend_function *fbc = call->func; - zval *ret; - zval retval; + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - EX(call) = call->prev_execute_data; - - const uint32_t no_discard = RETURN_VALUE_USED(opline) ? 0 : ZEND_ACC_NODISCARD; + orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) { - if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) { - zend_deprecated_function(fbc); - } - if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) { - zend_nodiscard_function(fbc); - } - if (UNEXPECTED(EG(exception) != NULL)) { - if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) { - OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func)); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_CV == IS_UNUSED) { + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; + } } - UNDEF_RESULT(); - if (!RETURN_VALUE_USED(opline)) { - ret = &retval; - ZVAL_UNDEF(ret); + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_DEREF(value); } - goto fcall_end; + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_CONST == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } else if (IS_CONST == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } + } else { + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + value = RT_CONSTANT((opline+1), (opline+1)->op1); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); } - } - - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { - ret = NULL; - if (RETURN_VALUE_USED(opline)) { - ret = EX_VAR(opline->result.var); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); } - - call->prev_execute_data = execute_data; - execute_data = call; - i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC); - - if (EXPECTED(zend_execute_ex == execute_ex)) { - LOAD_OPLINE_EX(); - SAVE_OPLINE(); - zend_observer_fcall_begin_specialized(execute_data, false); - ZEND_VM_ENTER_EX(); - } else { - SAVE_OPLINE_EX(); - zend_observer_fcall_begin_specialized(execute_data, false); - execute_data = EX(prev_execute_data); - LOAD_OPLINE(); - ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); - zend_execute_ex(call); + if (garbage) { + GC_DTOR_NO_REF(garbage); } } else { - ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); - if (1) { - ret = NULL; + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); - call->prev_execute_data = execute_data; - EG(current_execute_data) = call; + GC_ADDREF(obj); + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } -#if ZEND_DEBUG - bool should_throw = zend_internal_call_should_throw(fbc, call); -#endif + value = RT_CONSTANT((opline+1), (opline+1)->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_CONST & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } - ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval; - ZVAL_NULL(ret); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - zend_observer_fcall_begin_specialized(call, false); - if (!zend_execute_internal) { - /* saves one function call if zend_execute_internal is not used */ - fbc->internal_function.handler(call, ret); - } else { - zend_execute_internal(call, ret); - } -#if ZEND_DEBUG - if (!EG(exception) && call->func && !(call->func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE)) { - if (should_throw) { - zend_internal_call_arginfo_violation(call->func); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); } - ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, ret)); - ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) - ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); - zend_verify_internal_func_info(call->func, ret); - } -#endif - zend_observer_fcall_end(call, EG(exception) ? NULL : ret); - ZEND_VM_FCALL_INTERRUPT_CHECK(call); + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_CV == IS_UNUSED) { + zend_use_new_element_for_string(); - EG(current_execute_data) = execute_data; - goto fcall_end; - } + UNDEF_RESULT(); + } else { + dim = EX_VAR(opline->op2.var); + value = RT_CONSTANT((opline+1), (opline+1)->op1); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - if (0) { -fcall_end: - zend_vm_stack_free_args(call); - if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { - zend_free_extra_named_params(call->extra_named_params); - } + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if (!RETURN_VALUE_USED(opline)) { - i_zval_ptr_dtor(ret); + + UNDEF_RESULT(); + } else { + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + goto try_assign_dim_array; + } + } else { + zend_use_scalar_as_array(); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); +assign_dim_error: + + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } } + if (IS_CV != IS_UNUSED) { - if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) { - OBJ_RELEASE(Z_OBJ(call->This)); - } - zend_vm_stack_free_call_frame(call); - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - HANDLE_EXCEPTION(); } - ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); - ZEND_VM_CONTINUE(); + + + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GENERATOR_CREATE_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zval *return_value = EX(return_value); - - if (EXPECTED(return_value)) { - USE_OPLINE - zend_generator *generator; - zend_execute_data *gen_execute_data; - uint32_t num_args, used_stack, call_info; + USE_OPLINE + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; - SAVE_OPLINE(); - object_init_ex(return_value, zend_ce_generator); + SAVE_OPLINE(); + orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - /* - * Normally the execute_data is allocated on the VM stack (because it does - * not actually do any allocation and thus is faster). For generators - * though this behavior would be suboptimal, because the (rather large) - * structure would have to be copied back and forth every time execution is - * suspended or resumed. That's why for generators the execution context - * is allocated on heap. - */ - num_args = EX_NUM_ARGS(); - if (EXPECTED(num_args <= EX(func)->op_array.num_args)) { - used_stack = (ZEND_CALL_FRAME_SLOT + EX(func)->op_array.last_var + EX(func)->op_array.T) * sizeof(zval); - gen_execute_data = (zend_execute_data*)emalloc(used_stack); - used_stack = (ZEND_CALL_FRAME_SLOT + EX(func)->op_array.last_var) * sizeof(zval); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_CV == IS_UNUSED) { + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + ZVAL_DEREF(value); + } + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_TMP_VAR == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } else if (IS_TMP_VAR == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } } else { - used_stack = (ZEND_CALL_FRAME_SLOT + num_args + EX(func)->op_array.last_var + EX(func)->op_array.T - EX(func)->op_array.num_args) * sizeof(zval); - gen_execute_data = (zend_execute_data*)emalloc(used_stack); + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); } - memcpy(gen_execute_data, execute_data, used_stack); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); - /* Save execution context in generator object. */ - generator = (zend_generator *) Z_OBJ_P(EX(return_value)); - generator->func = gen_execute_data->func; - generator->execute_data = gen_execute_data; - generator->frozen_call_stack = NULL; - generator->execute_fake.opline = NULL; - generator->execute_fake.func = NULL; - generator->execute_fake.prev_execute_data = NULL; - ZVAL_OBJ(&generator->execute_fake.This, (zend_object *) generator); + GC_ADDREF(obj); + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } - gen_execute_data->opline = opline; - /* EX(return_value) keeps pointer to zend_object (not a real zval) */ - gen_execute_data->return_value = (zval*)generator; - call_info = Z_TYPE_INFO(EX(This)); - if ((call_info & Z_TYPE_MASK) == IS_OBJECT - && (!(call_info & (ZEND_CALL_CLOSURE|ZEND_CALL_RELEASE_THIS)) - /* Bug #72523 */ - || UNEXPECTED(zend_execute_ex != execute_ex))) { - ZEND_ADD_CALL_FLAG_EX(call_info, ZEND_CALL_RELEASE_THIS); - Z_ADDREF(gen_execute_data->This); - } - ZEND_ADD_CALL_FLAG_EX(call_info, (ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED | ZEND_CALL_GENERATOR)); - Z_TYPE_INFO(gen_execute_data->This) = call_info; - gen_execute_data->prev_execute_data = NULL; + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } - call_info = EX_CALL_INFO(); - EG(current_execute_data) = EX(prev_execute_data); - if (EXPECTED(!(call_info & (ZEND_CALL_TOP|ZEND_CALL_ALLOCATED)))) { - EG(vm_stack_top) = (zval*)execute_data; - execute_data = EX(prev_execute_data); - LOAD_NEXT_OPLINE(); - ZEND_VM_LEAVE(); - } else if (EXPECTED(!(call_info & ZEND_CALL_TOP))) { - zend_execute_data *old_execute_data = execute_data; - execute_data = EX(prev_execute_data); - zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); - LOAD_NEXT_OPLINE(); - ZEND_VM_LEAVE(); + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_CV == IS_UNUSED) { + zend_use_new_element_for_string(); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + } else { + dim = EX_VAR(opline->op2.var); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + } else { + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + goto try_assign_dim_array; + } } else { - ZEND_VM_RETURN(); + zend_use_scalar_as_array(); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); +assign_dim_error: + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } - } else { - ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); } + if (IS_CV != IS_UNUSED) { + + + } + + + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t _arg_num, zval *_arg); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_UNPACK_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *args; - uint32_t arg_num; + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - args = get_zval_ptr_undef(opline->op1_type, opline->op1, BP_VAR_R); - arg_num = ZEND_CALL_NUM_ARGS(EX(call)) + 1; - -send_again: - if (EXPECTED(Z_TYPE_P(args) == IS_ARRAY)) { - HashTable *ht = Z_ARRVAL_P(args); - zval *arg, *top; - zend_string *name; - bool have_named_params = 0; - - zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht)); - - // TODO: Speed this up using a flag that specifies whether there are any ref parameters. - if ((opline->op1_type & (IS_VAR|IS_CV)) && Z_REFCOUNT_P(args) > 1) { - uint32_t tmp_arg_num = arg_num; - bool separate = 0; + orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - /* check if any of arguments are going to be passed by reference */ - ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) { - if (UNEXPECTED(name)) { - void *cache_slot[2] = {NULL, NULL}; - tmp_arg_num = zend_get_arg_offset_by_name( - EX(call)->func, name, cache_slot) + 1; + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_CV == IS_UNUSED) { + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); } - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, tmp_arg_num)) { - separate = 1; - break; + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; } - tmp_arg_num++; - } ZEND_HASH_FOREACH_END(); - if (separate) { - SEPARATE_ARRAY(args); - ht = Z_ARRVAL_P(args); } - } - - ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) { - if (UNEXPECTED(name)) { - void *cache_slot[2] = {NULL, NULL}; - have_named_params = 1; - top = zend_handle_named_arg(&EX(call), name, &arg_num, cache_slot); - if (UNEXPECTED(!top)) { - FREE_OP(opline->op1_type, opline->op1.var); - HANDLE_EXCEPTION(); + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_DEREF(value); + } + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_CV == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); } - } else { - if (have_named_params) { - zend_throw_error(NULL, - "Cannot use positional argument after named argument during unpacking"); - FREE_OP(opline->op1_type, opline->op1.var); - HANDLE_EXCEPTION(); + } else if (IS_CV == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); } - - top = ZEND_CALL_ARG(EX(call), arg_num); - ZEND_CALL_NUM_ARGS(EX(call))++; - } - - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - if (Z_ISREF_P(arg)) { - Z_ADDREF_P(arg); - ZVAL_REF(top, Z_REF_P(arg)); - } else if (opline->op1_type & (IS_VAR|IS_CV)) { - /* array is already separated above */ - ZVAL_MAKE_REF_EX(arg, 2); - ZVAL_REF(top, Z_REF_P(arg)); - } else { - Z_TRY_ADDREF_P(arg); - ZVAL_NEW_REF(top, arg); + } else if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); } + } + } else { + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { - ZVAL_COPY_DEREF(top, arg); + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); + } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); - arg_num++; - } ZEND_HASH_FOREACH_END(); + GC_ADDREF(obj); + dim = EX_VAR(opline->op2.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } - } else if (EXPECTED(Z_TYPE_P(args) == IS_OBJECT)) { - zend_class_entry *ce = Z_OBJCE_P(args); - zend_object_iterator *iter; - bool have_named_params = 0; + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_CV & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } - if (!ce || !ce->get_iterator) { - zend_type_error("Only arrays and Traversables can be unpacked, %s given", zend_zval_value_name(args)); - } else { + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - iter = ce->get_iterator(ce, args, 0); - if (UNEXPECTED(!iter)) { - FREE_OP(opline->op1_type, opline->op1.var); - if (!EG(exception)) { - zend_throw_exception_ex( - NULL, 0, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name) - ); - } - HANDLE_EXCEPTION(); - } - const zend_object_iterator_funcs *funcs = iter->funcs; - if (funcs->rewind) { - funcs->rewind(iter); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_CV == IS_UNUSED) { + zend_use_new_element_for_string(); - for (; funcs->valid(iter) == SUCCESS; ++arg_num) { - zval *arg, *top; - if (UNEXPECTED(EG(exception) != NULL)) { - break; - } + UNDEF_RESULT(); + } else { + dim = EX_VAR(opline->op2.var); + value = EX_VAR((opline+1)->op1.var); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - arg = funcs->get_current_data(iter); - if (UNEXPECTED(EG(exception) != NULL)) { - break; - } - zend_string *name = NULL; - if (funcs->get_current_key) { - zval key; - funcs->get_current_key(iter, &key); - if (UNEXPECTED(EG(exception) != NULL)) { - break; - } + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if (UNEXPECTED(Z_TYPE(key) != IS_LONG)) { - if (UNEXPECTED(Z_TYPE(key) != IS_STRING)) { - zend_throw_error(NULL, - "Keys must be of type int|string during argument unpacking"); - zval_ptr_dtor(&key); - break; - } - name = Z_STR_P(&key); + UNDEF_RESULT(); + } else { + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); - zend_ulong tmp; - if (ZEND_HANDLE_NUMERIC(name, tmp)) { - name = NULL; - } + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; } } + goto try_assign_dim_array; + } + } else { + zend_use_scalar_as_array(); + dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); +assign_dim_error: - if (UNEXPECTED(name)) { - void *cache_slot[2] = {NULL, NULL}; - have_named_params = 1; - top = zend_handle_named_arg(&EX(call), name, &arg_num, cache_slot); - if (UNEXPECTED(!top)) { - zend_string_release(name); - break; - } - ZVAL_DEREF(arg); - Z_TRY_ADDREF_P(arg); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + if (IS_CV != IS_UNUSED) { - if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - zend_error( - E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()" - " by unpacking a Traversable, passing by-value instead", arg_num, - EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "", - EX(call)->func->common.scope ? "::" : "", - ZSTR_VAL(EX(call)->func->common.function_name) - ); - ZVAL_NEW_REF(top, arg); - } else { - ZVAL_COPY_VALUE(top, arg); - } - zend_string_release(name); - } else { - if (have_named_params) { - zend_throw_error(NULL, - "Cannot use positional argument after named argument during unpacking"); - break; - } + } - zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1); - top = ZEND_CALL_ARG(EX(call), arg_num); - ZVAL_DEREF(arg); - Z_TRY_ADDREF_P(arg); - if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - zend_error( - E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()" - " by unpacking a Traversable, passing by-value instead", arg_num, - EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "", - EX(call)->func->common.scope ? "::" : "", - ZSTR_VAL(EX(call)->func->common.function_name) - ); - ZVAL_NEW_REF(top, arg); - } else { - ZVAL_COPY_VALUE(top, arg); - } + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} - ZEND_CALL_NUM_ARGS(EX(call))++; - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + zval *variable_ptr; - funcs->move_forward(iter); - } + SAVE_OPLINE(); + value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = EX_VAR(opline->op1.var); - zend_iterator_dtor(iter); + if (0 || UNEXPECTED(0)) { + zend_refcounted *garbage = NULL; + + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); } - } else if (EXPECTED(Z_ISREF_P(args))) { - args = Z_REFVAL_P(args); - goto send_again; - } else { - if (opline->op1_type == IS_CV && UNEXPECTED(Z_TYPE_P(args) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (garbage) { + GC_DTOR_NO_REF(garbage); } - zend_type_error("Only arrays and Traversables can be unpacked, %s given", zend_zval_value_name(args)); + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); } - FREE_OP(opline->op1_type, opline->op1.var); + + /* zend_assign_to_variable() always takes care of op2, never free it! */ + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_ARRAY_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_SPEC_CV_CV_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *args; + zval *value; + zval *variable_ptr; SAVE_OPLINE(); - args = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R); + value = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = EX_VAR(opline->op1.var); - if (UNEXPECTED(Z_TYPE_P(args) != IS_ARRAY)) { - if ((opline->op1_type & (IS_VAR|IS_CV)) && Z_ISREF_P(args)) { - args = Z_REFVAL_P(args); - if (EXPECTED(Z_TYPE_P(args) == IS_ARRAY)) { - goto send_array; - } + if (0 || UNEXPECTED(1)) { + zend_refcounted *garbage = NULL; + + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(1)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); } - zend_type_error("call_user_func_array(): Argument #2 ($args) must be of type array, %s given", zend_zval_value_name(args)); - FREE_OP(opline->op2_type, opline->op2.var); - FREE_OP(opline->op1_type, opline->op1.var); - HANDLE_EXCEPTION(); } else { - uint32_t arg_num; - HashTable *ht; - zval *arg, *param; + value = zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); + } -send_array: - ht = Z_ARRVAL_P(args); - if (opline->op2_type != IS_UNUSED) { - /* We don't need to handle named params in this case, - * because array_slice() is called with $preserve_keys == false. */ - zval *op2 = get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R); - uint32_t skip = opline->extended_value; - uint32_t count = zend_hash_num_elements(ht); - zend_long len; - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - len = Z_LVAL_P(op2); - } else if (Z_TYPE_P(op2) == IS_NULL) { - len = count - skip; - } else if (EX_USES_STRICT_TYPES() - || !zend_parse_arg_long_weak(op2, &len, /* arg_num */ 3)) { - zend_type_error( - "array_slice(): Argument #3 ($length) must be of type ?int, %s given", - zend_zval_value_name(op2)); - FREE_OP(opline->op2_type, opline->op2.var); - FREE_OP(opline->op1_type, opline->op1.var); - HANDLE_EXCEPTION(); - } - if (len < 0) { - len += (zend_long)(count - skip); - } - if (skip < count && len > 0) { - if (len > (zend_long)(count - skip)) { - len = (zend_long)(count - skip); - } - zend_vm_stack_extend_call_frame(&EX(call), 0, len); - arg_num = 1; - param = ZEND_CALL_ARG(EX(call), 1); - ZEND_HASH_FOREACH_VAL(ht, arg) { - bool must_wrap = 0; - if (skip > 0) { - skip--; - continue; - } else if ((zend_long)(arg_num - 1) >= len) { - break; - } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - if (UNEXPECTED(!Z_ISREF_P(arg))) { - if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - /* By-value send is not allowed -- emit a warning, - * but still perform the call. */ - zend_param_must_be_ref(EX(call)->func, arg_num); - must_wrap = 1; - } - } - } else { - if (Z_ISREF_P(arg) && - !(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { - /* don't separate references for __call */ - arg = Z_REFVAL_P(arg); - } - } - if (EXPECTED(!must_wrap)) { - ZVAL_COPY(param, arg); - } else { - Z_TRY_ADDREF_P(arg); - ZVAL_NEW_REF(param, arg); - } - ZEND_CALL_NUM_ARGS(EX(call))++; - arg_num++; - param++; - } ZEND_HASH_FOREACH_END(); - } - FREE_OP(opline->op2_type, opline->op2.var); - } else { - zend_string *name; - bool have_named_params; - zend_vm_stack_extend_call_frame(&EX(call), 0, zend_hash_num_elements(ht)); - arg_num = 1; - param = ZEND_CALL_ARG(EX(call), 1); - have_named_params = 0; - ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) { - if (name) { - void *cache_slot[2] = {NULL, NULL}; - have_named_params = 1; - param = zend_handle_named_arg(&EX(call), name, &arg_num, cache_slot); - if (!param) { - FREE_OP(opline->op1_type, opline->op1.var); - HANDLE_EXCEPTION(); - } - } else if (have_named_params) { - zend_throw_error(NULL, - "Cannot use positional argument after named argument"); - FREE_OP(opline->op1_type, opline->op1.var); - HANDLE_EXCEPTION(); - } + /* zend_assign_to_variable() always takes care of op2, never free it! */ - bool must_wrap = 0; - if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - if (UNEXPECTED(!Z_ISREF_P(arg))) { - if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - /* By-value send is not allowed -- emit a warning, - * but still perform the call. */ - zend_param_must_be_ref(EX(call)->func, arg_num); - must_wrap = 1; - } - } - } else { - if (Z_ISREF_P(arg) && - !(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { - /* don't separate references for __call */ - arg = Z_REFVAL_P(arg); - } - } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - if (EXPECTED(!must_wrap)) { - ZVAL_COPY(param, arg); - } else { - Z_TRY_ADDREF_P(arg); - ZVAL_NEW_REF(param, arg); - } - if (!name) { - ZEND_CALL_NUM_ARGS(EX(call))++; - arg_num++; - param++; - } - } ZEND_HASH_FOREACH_END(); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_REF_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *variable_ptr; + zval *value_ptr; + zend_refcounted *garbage = NULL; + + SAVE_OPLINE(); + value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = EX_VAR(opline->op1.var); + + if (IS_CV == IS_VAR && + UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) { + + zend_throw_error(NULL, "Cannot assign by reference to an array dimension of an object"); + variable_ptr = &EG(uninitialized_zval); + } else if (IS_CV == IS_VAR && + opline->extended_value == ZEND_RETURNS_FUNCTION && + UNEXPECTED(!Z_ISREF_P(value_ptr))) { + + variable_ptr = zend_wrong_assign_to_variable_reference( + variable_ptr, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_variable_reference(variable_ptr, value_ptr, &garbage); + } + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr); } - FREE_OP(opline->op1_type, opline->op1.var); + + if (garbage) { + GC_DTOR(garbage); + } + + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_missing_arg_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *property, *container, *value_ptr; SAVE_OPLINE(); - zend_missing_arg_error(execute_data); - HANDLE_EXCEPTION(); -} + container = EX_VAR(opline->op1.var); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_verify_recv_arg_type_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1); -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RECV_NOTYPE_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - uint32_t arg_num = opline->op1.num; + value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(arg_num > EX_NUM_ARGS())) { - ZEND_VM_TAIL_CALL(zend_missing_arg_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (1) { + if (IS_CV == IS_UNUSED) { + if (IS_CV == IS_CONST) { + zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } + } else { + if (IS_CV == IS_CONST) { + zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } + } + } else { + zend_assign_to_property_reference(container, IS_CV, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC); } - ZEND_VM_NEXT_OPCODE(); + + + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_case_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_UNPACK_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1; - HashTable *result_ht; + zval *property, *container, *value_ptr; SAVE_OPLINE(); - op1 = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R); - result_ht = Z_ARRVAL_P(EX_VAR(opline->result.var)); -add_unpack_again: - if (EXPECTED(Z_TYPE_P(op1) == IS_ARRAY)) { - HashTable *ht = Z_ARRVAL_P(op1); - zval *val; + container = EX_VAR(opline->op1.var); + property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if (HT_IS_PACKED(ht) && (zend_hash_num_elements(result_ht) == 0 || HT_IS_PACKED(result_ht))) { - /* zend_hash_extend() skips initialization when the number of elements is 0, - * but the code below expects that result_ht is initialized as packed. - * We can just skip the work in that case. */ - if (result_ht->nNumUsed + zend_hash_num_elements(ht) > 0) { - zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1); - ZEND_HASH_FILL_PACKED(result_ht) { - ZEND_HASH_PACKED_FOREACH_VAL(ht, val) { - if (UNEXPECTED(Z_ISREF_P(val)) && - UNEXPECTED(Z_REFCOUNT_P(val) == 1)) { - val = Z_REFVAL_P(val); - } - Z_TRY_ADDREF_P(val); - ZEND_HASH_FILL_ADD(val); - } ZEND_HASH_FOREACH_END(); - } ZEND_HASH_FILL_END(); + value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); + + if (1) { + if (IS_CV == IS_UNUSED) { + if (IS_CV == IS_CONST) { + zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } else { - zend_string *key; - - ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { - if (UNEXPECTED(Z_ISREF_P(val)) && - UNEXPECTED(Z_REFCOUNT_P(val) == 1)) { - val = Z_REFVAL_P(val); - } - Z_TRY_ADDREF_P(val); - if (key) { - zend_hash_update(result_ht, key, val); - } else { - if (!zend_hash_next_index_insert(result_ht, val)) { - zend_cannot_add_element(); - zval_ptr_dtor_nogc(val); - break; - } - } - } ZEND_HASH_FOREACH_END(); + if (IS_CV == IS_CONST) { + zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_OBJECT)) { - zend_class_entry *ce = Z_OBJCE_P(op1); - zend_object_iterator *iter; + } else { + zend_assign_to_property_reference(container, IS_CV, property, IS_CV, value_ptr OPLINE_CC EXECUTE_DATA_CC); + } - if (!ce || !ce->get_iterator) { - zend_type_error("Only arrays and Traversables can be unpacked, %s given", zend_zval_value_name(op1)); - } else { - iter = ce->get_iterator(ce, op1, 0); - if (UNEXPECTED(!iter)) { - FREE_OP(opline->op1_type, opline->op1.var); - if (!EG(exception)) { - zend_throw_exception_ex( - NULL, 0, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name) - ); - } - HANDLE_EXCEPTION(); - } - const zend_object_iterator_funcs *funcs = iter->funcs; - if (funcs->rewind) { - funcs->rewind(iter); - } - for (; funcs->valid(iter) == SUCCESS; ) { - zval *val; - if (UNEXPECTED(EG(exception) != NULL)) { - break; - } - val = funcs->get_current_data(iter); - if (UNEXPECTED(EG(exception) != NULL)) { - break; - } - zval key; - if (funcs->get_current_key) { - funcs->get_current_key(iter, &key); - if (UNEXPECTED(EG(exception) != NULL)) { - break; - } + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} - if (UNEXPECTED(Z_TYPE(key) != IS_LONG && Z_TYPE(key) != IS_STRING)) { - zend_throw_error(NULL, - "Keys must be of type int|string during array unpacking"); - zval_ptr_dtor(&key); - break; - } - } else { - ZVAL_UNDEF(&key); - } +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + zend_string *op1_str, *op2_str, *str; - ZVAL_DEREF(val); - Z_TRY_ADDREF_P(val); - zend_ulong num_key; - if (Z_TYPE(key) == IS_STRING && !ZEND_HANDLE_NUMERIC(Z_STR(key), num_key)) { - zend_hash_update(result_ht, Z_STR(key), val); - zval_ptr_dtor_str(&key); - } else { - zval_ptr_dtor(&key); - if (!zend_hash_next_index_insert(result_ht, val)) { - zend_cannot_add_element(); - zval_ptr_dtor_nogc(val); - break; - } - } + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); - funcs->move_forward(iter); - if (UNEXPECTED(EG(exception))) { - break; - } + if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); } + } else if (IS_CV != IS_CONST && IS_CV != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); - zend_iterator_dtor(iter); + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } } - } else if (EXPECTED(Z_ISREF_P(op1))) { - op1 = Z_REFVAL_P(op1); - goto add_unpack_again; - } else { - zend_throw_error(NULL, "Only arrays and Traversables can be unpacked, %s given", zend_zval_value_name(op1)); + ZEND_VM_NEXT_OPCODE(); } - FREE_OP(opline->op1_type, opline->op1.var); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_STATIC_PROP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *varname; - zend_string *name, *tmp_name = NULL; - zend_class_entry *ce; - SAVE_OPLINE(); - - if (opline->op2_type == IS_CONST) { - ce = CACHED_PTR(opline->extended_value); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - FREE_OP(opline->op1_type, opline->op1.var); - HANDLE_EXCEPTION(); - } - /*CACHE_PTR(opline->extended_value, ce);*/ - } - } else if (opline->op2_type == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - FREE_OP(opline->op1_type, opline->op1.var); - HANDLE_EXCEPTION(); + if (IS_CV == IS_CONST) { + op1_str = Z_STR_P(op1); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + op1_str = zend_string_copy(Z_STR_P(op1)); + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } + op1_str = zval_get_string_func(op1); + } + if (IS_CV == IS_CONST) { + op2_str = Z_STR_P(op2); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + op2_str = zend_string_copy(Z_STR_P(op2)); } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + } + op2_str = zval_get_string_func(op2); } + do { + if (IS_CV != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + zend_string_release_ex(op1_str, 0); + break; + } + } + if (IS_CV != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + zend_string_release_ex(op2_str, 0); + break; + } + } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - varname = get_zval_ptr_undef(opline->op1_type, opline->op1, BP_VAR_R); - if (opline->op1_type == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - } else { - if (opline->op1_type == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = ZVAL_UNDEFINED_OP1(); + ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CV != IS_CONST) { + zend_string_release_ex(op1_str, 0); } - name = zval_try_get_tmp_string(varname, &tmp_name); - if (UNEXPECTED(!name)) { - FREE_OP(opline->op1_type, opline->op1.var); - HANDLE_EXCEPTION(); + if (IS_CV != IS_CONST) { + zend_string_release_ex(op2_str, 0); } - } + } while (0); + + - zend_std_unset_static_property(ce, name); - zend_tmp_string_release(tmp_name); - FREE_OP(opline->op1_type, opline->op1.var); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_fe_fetch_object_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *array; - zval *value; - uint32_t value_type; - HashTable *fe_ht; - HashPosition pos; - Bucket *p; - zend_object_iterator *iter; + zval *function_name; + zval *object; + zend_function *fbc; + zend_class_entry *called_scope; + zend_object *obj; + zend_execute_data *call; + uint32_t call_info; - array = EX_VAR(opline->op1.var); SAVE_OPLINE(); - ZEND_ASSERT(Z_TYPE_P(array) == IS_OBJECT); - if ((iter = zend_iterator_unwrap(array)) == NULL) { - /* plain object */ + object = EX_VAR(opline->op1.var); - fe_ht = Z_OBJPROP_P(array); - pos = zend_hash_iterator_pos(Z_FE_ITER_P(array), fe_ht); - p = fe_ht->arData + pos; - while (1) { - if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { - /* reached end of iteration */ - goto fe_fetch_r_exit; - } - pos++; - value = &p->val; - value_type = Z_TYPE_INFO_P(value); - if (EXPECTED(value_type != IS_UNDEF)) { - if (UNEXPECTED(value_type == IS_INDIRECT)) { - value = Z_INDIRECT_P(value); - value_type = Z_TYPE_INFO_P(value); - if (EXPECTED(value_type != IS_UNDEF) - && EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key, 0) == SUCCESS)) { - break; - } - } else if (EXPECTED(Z_OBJCE_P(array)->default_properties_count == 0) - || !p->key - || zend_check_property_access(Z_OBJ_P(array), p->key, 1) == SUCCESS) { + if (IS_CV != IS_CONST) { + function_name = EX_VAR(opline->op2.var); + } + + if (IS_CV != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } - p++; - } - EG(ht_iterators)[Z_FE_ITER_P(array)].pos = pos; - if (RETURN_VALUE_USED(opline)) { - if (UNEXPECTED(!p->key)) { - ZVAL_LONG(EX_VAR(opline->result.var), p->h); - } else if (ZSTR_VAL(p->key)[0]) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); - } else { - const char *class_name, *prop_name; - size_t prop_name_len; - zend_unmangle_property_name_ex( - p->key, &class_name, &prop_name, &prop_name_len); - ZVAL_STRINGL(EX_VAR(opline->result.var), prop_name, prop_name_len); - } - } - } else { - const zend_object_iterator_funcs *funcs = iter->funcs; - if (EXPECTED(++iter->index > 0)) { - /* This could cause an endless loop if index becomes zero again. - * In case that ever happens we need an additional flag. */ - funcs->move_forward(iter); - if (UNEXPECTED(EG(exception) != NULL)) { - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - if (UNEXPECTED(funcs->valid(iter) == FAILURE)) { - /* reached end of iteration */ - if (UNEXPECTED(EG(exception) != NULL)) { - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } -fe_fetch_r_exit: - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } - } - value = funcs->get_current_data(iter); - if (UNEXPECTED(EG(exception) != NULL)) { - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - if (!value) { - /* failure in get_current_data */ - goto fe_fetch_r_exit; - } - if (RETURN_VALUE_USED(opline)) { - if (funcs->get_current_key) { - funcs->get_current_key(iter, EX_VAR(opline->result.var)); + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); if (UNEXPECTED(EG(exception) != NULL)) { - UNDEF_RESULT(); + + HANDLE_EXCEPTION(); } - } else { - ZVAL_LONG(EX_VAR(opline->result.var), iter->index); } - } - value_type = Z_TYPE_INFO_P(value); - } + zend_throw_error(NULL, "Method name must be a string"); - if (EXPECTED(opline->op2_type == IS_CV)) { - zval *variable_ptr = EX_VAR(opline->op2.var); - zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); - } else { - zval *res = EX_VAR(opline->op2.var); - zend_refcounted *gc = Z_COUNTED_P(value); - ZVAL_COPY_VALUE_EX(res, value, gc, value_type); - if (Z_TYPE_INFO_REFCOUNTED(value_type)) { - GC_ADDREF(gc); - } + + + HANDLE_EXCEPTION(); + } while (0); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - bool result; + if (IS_CV == IS_UNUSED) { + obj = Z_OBJ_P(object); + } else { + do { + if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + } else { + if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + zend_reference *ref = Z_REF_P(object); - SAVE_OPLINE(); + object = &ref->val; + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + if (IS_CV & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } + break; + } + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + object = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_CV != IS_CONST) { - value = zend_fetch_static_property_address(NULL, opline->extended_value & ~ZEND_ISEMPTY, BP_VAR_IS, 0 OPLINE_CC EXECUTE_DATA_CC); - if (!(opline->extended_value & ZEND_ISEMPTY)) { - result = value != NULL && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - } else { - result = value == NULL || !i_zend_is_true(value); - } + } + HANDLE_EXCEPTION(); + } + } + if (IS_CV == IS_CONST) { + function_name = EX_VAR(opline->op2.var); + } + zend_invalid_method_call(object, function_name); - ZEND_VM_SMART_BRANCH(result, 1); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BEGIN_SILENCE_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting)); - if (!E_HAS_ONLY_FATAL_ERRORS(EG(error_reporting))) { - do { - /* Do not silence fatal errors */ - EG(error_reporting) &= E_FATAL_ERRORS; - if (!EG(error_reporting_ini_entry)) { - zval *zv = zend_hash_find_known_hash(EG(ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING)); - if (zv) { - EG(error_reporting_ini_entry) = (zend_ini_entry *)Z_PTR_P(zv); - } else { - break; - } - } - if (!EG(error_reporting_ini_entry)->modified) { - if (!EG(modified_ini_directives)) { - ALLOC_HASHTABLE(EG(modified_ini_directives)); - zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0); - } - if (EXPECTED(zend_hash_add_ptr(EG(modified_ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING), EG(error_reporting_ini_entry)) != NULL)) { - EG(error_reporting_ini_entry)->orig_value = EG(error_reporting_ini_entry)->value; - EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable; - EG(error_reporting_ini_entry)->modified = 1; - } + HANDLE_EXCEPTION(); } } while (0); } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_EXT_STMT_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - if (!EG(no_extensions)) { - SAVE_OPLINE(); - zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_statement_handler, execute_data); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_EXT_FCALL_BEGIN_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE + called_scope = obj->ce; - if (!EG(no_extensions)) { - SAVE_OPLINE(); - zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_begin_handler, execute_data); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); -} + if (IS_CV == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else { + zend_object *orig_obj = obj; -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_EXT_FCALL_END_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE + if (IS_CV == IS_CONST) { + function_name = EX_VAR(opline->op2.var); + } - if (!EG(no_extensions)) { - SAVE_OPLINE(); - zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_end_handler, execute_data); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); -} + /* First, locate the function. */ + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_ANON_CLASS_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zval *zv; - zend_class_entry *ce; - USE_OPLINE - ce = CACHED_PTR(opline->extended_value); - if (UNEXPECTED(ce == NULL)) { - zend_string *rtd_key = Z_STR_P(RT_CONSTANT(opline, opline->op1)); - zv = zend_hash_find_known_hash(EG(class_table), rtd_key); - ZEND_ASSERT(zv != NULL); - ce = Z_CE_P(zv); - if (!(ce->ce_flags & ZEND_ACC_LINKED)) { - SAVE_OPLINE(); - ce = zend_do_link_class(ce, (opline->op2_type == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL, rtd_key); - if (EG(exception)) { - HANDLE_EXCEPTION(); + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); } + HANDLE_EXCEPTION(); + } + if (IS_CV == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(obj == orig_obj)) { + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); + } + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); } - CACHE_PTR(opline->extended_value, ce); } - Z_CE_P(EX_VAR(opline->result.var)) = ce; - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_FUNCTION_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zend_function *func; - USE_OPLINE + if (IS_CV != IS_CONST) { - SAVE_OPLINE(); - func = (zend_function *) EX(func)->op_array.dynamic_func_defs[opline->op2.num]; - do_bind_function(func, RT_CONSTANT(opline, opline->op1)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_TICKS_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE + } - if (++EG(ticks_count) >= opline->extended_value) { - EG(ticks_count) = 0; - if (zend_ticks_function) { - SAVE_OPLINE(); - zend_fiber_switch_block(); - zend_ticks_function(opline->extended_value); - zend_fiber_switch_unblock(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { + if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; + } else if (IS_CV & (IS_VAR|IS_TMP_VAR|IS_CV)) { + if (IS_CV == IS_CV) { + GC_ADDREF(obj); /* For $this pointer */ + } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_EXT_NOP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, obj); + call->prev_execute_data = EX(call); + EX(call) = call; ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NOP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *expr_ptr, new_expr; - ZEND_VM_NEXT_OPCODE(); -} - -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_dispatch_try_catch_finally_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t try_catch_offset, uint32_t op_num); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_HANDLE_EXCEPTION_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - const zend_op *throw_op = EG(opline_before_exception); + SAVE_OPLINE(); + if ((IS_CV == IS_VAR || IS_CV == IS_CV) && + UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { + expr_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); + if (Z_ISREF_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } else { + ZVAL_MAKE_REF_EX(expr_ptr, 2); + } - /* Exception was thrown before executing any op */ - if (UNEXPECTED(!throw_op)) { - ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX -1, 0)); - } - uint32_t throw_op_num = throw_op - EX(func)->op_array.opcodes; - uint32_t current_try_catch_offset = -1; + } else { + expr_ptr = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + if (IS_CV == IS_TMP_VAR) { + /* pass */ + } else if (IS_CV == IS_CONST) { + Z_TRY_ADDREF_P(expr_ptr); + } else if (IS_CV == IS_CV) { + ZVAL_DEREF(expr_ptr); + Z_TRY_ADDREF_P(expr_ptr); + } else /* if (IS_CV == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(expr_ptr); - if ((throw_op->opcode == ZEND_FREE || throw_op->opcode == ZEND_FE_FREE) - && throw_op->extended_value & ZEND_FREE_ON_RETURN) { - /* exceptions thrown because of loop var destruction on return/break/... - * are logically thrown at the end of the foreach loop, so adjust the - * throw_op_num. - */ - const zend_live_range *range = find_live_range( - &EX(func)->op_array, throw_op_num, throw_op->op1.var); - /* free op1 of the corresponding RETURN */ - for (uint32_t i = throw_op_num; i < range->end; i++) { - if (EX(func)->op_array.opcodes[i].opcode == ZEND_FREE - || EX(func)->op_array.opcodes[i].opcode == ZEND_FE_FREE) { - /* pass */ - } else { - if (EX(func)->op_array.opcodes[i].opcode == ZEND_RETURN - && (EX(func)->op_array.opcodes[i].op1_type & (IS_VAR|IS_TMP_VAR))) { - zval_ptr_dtor(EX_VAR(EX(func)->op_array.opcodes[i].op1.var)); + expr_ptr = Z_REFVAL_P(expr_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + ZVAL_COPY_VALUE(&new_expr, expr_ptr); + expr_ptr = &new_expr; + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); } - break; } } - throw_op_num = range->end; - } - - /* Find the innermost try/catch/finally the exception was thrown in */ - for (uint32_t i = 0; i < EX(func)->op_array.last_try_catch; i++) { - zend_try_catch_element *try_catch = &EX(func)->op_array.try_catch_array[i]; - if (try_catch->try_op > throw_op_num) { - /* further blocks will not be relevant... */ - break; - } - if (throw_op_num < try_catch->catch_op || throw_op_num < try_catch->finally_end) { - current_try_catch_offset = i; - } } - cleanup_unfinished_calls(execute_data, throw_op_num); + if (IS_CV != IS_UNUSED) { + zval *offset = EX_VAR(opline->op2.var); + zend_string *str; + zend_ulong hval; - if (throw_op->result_type & (IS_VAR | IS_TMP_VAR)) { - switch (throw_op->opcode) { - case ZEND_ADD_ARRAY_ELEMENT: - case ZEND_ADD_ARRAY_UNPACK: - case ZEND_ROPE_INIT: - case ZEND_ROPE_ADD: - break; /* exception while building structures, live range handling will free those */ +add_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_CV != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index; + } + } +str_index: + zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index: + zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto add_again; + } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { + zval tmp; + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_COPY(&tmp, expr_ptr); + } + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + /* A userland error handler can do funky things to the expression, so reset it */ + zval_ptr_dtor(expr_ptr); + ZVAL_COPY_VALUE(expr_ptr, &tmp); + } + if (UNEXPECTED(EG(exception))) { + zval_ptr_dtor_nogc(expr_ptr); + HANDLE_EXCEPTION(); + } + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + goto num_index; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); + hval = Z_RES_HANDLE_P(offset); + goto num_index; + } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else { + zend_illegal_array_offset_access(offset); + zval_ptr_dtor_nogc(expr_ptr); + } - case ZEND_FETCH_CLASS: - case ZEND_DECLARE_ANON_CLASS: - break; /* return value is zend_class_entry pointer */ - default: - /* smart branch opcodes may not initialize result */ - if (!zend_is_smart_branch(throw_op)) { - zval_ptr_dtor_nogc(EX_VAR(throw_op->result.var)); - } + } else { + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(expr_ptr); } } - - ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX current_try_catch_offset, throw_op_num)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_USER_OPCODE_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_INIT_ARRAY_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zval *array; + uint32_t size; USE_OPLINE - int ret; SAVE_OPLINE(); - ret = zend_user_opcode_handlers[opline->opcode](execute_data); - opline = EX(opline); - - switch (ret) { - case ZEND_USER_OPCODE_CONTINUE: - ZEND_VM_CONTINUE(); - case ZEND_USER_OPCODE_RETURN: - if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) { - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - EG(current_execute_data) = EX(prev_execute_data); - zend_generator_close(generator, 1); - ZEND_VM_RETURN(); - } else { - ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); - } - case ZEND_USER_OPCODE_ENTER: - ZEND_VM_ENTER(); - case ZEND_USER_OPCODE_LEAVE: - ZEND_VM_LEAVE(); - case ZEND_USER_OPCODE_DISPATCH: - ZEND_VM_DISPATCH(opline->opcode, opline); - default: - ZEND_VM_DISPATCH((uint8_t)(ret & 0xff), opline); + array = EX_VAR(opline->result.var); + if (IS_CV != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_ARR(array, zend_new_array(0)); + ZEND_VM_NEXT_OPCODE(); } } -static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *container; + zval *offset; + zend_ulong hval; + zend_string *key; SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot yield from finally in a force-closed generator"); - FREE_OP(opline->op2_type, opline->op2.var); - FREE_OP(opline->op1_type, opline->op1.var); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); + container = EX_VAR(opline->op1.var); + offset = EX_VAR(opline->op2.var); + + do { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + +unset_dim_array: + SEPARATE_ARRAY(container); + ht = Z_ARRVAL_P(container); +offset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + key = Z_STR_P(offset); + if (IS_CV != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(key, hval)) { + goto num_index_dim; + } + } +str_index_dim: + ZEND_ASSERT(ht != &EG(symbol_table)); + zend_hash_del(ht, key); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_dim: + zend_hash_index_del(ht, hval); + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto offset_again; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + /* The array may be destroyed while throwing a warning in case the float is not representable as an int. + * Temporarily increase the refcount to detect this situation. */ + GC_TRY_ADDREF(ht); + hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + break; + } + if (EG(exception)) { + break; + } + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_NULL) { + key = ZSTR_EMPTY_ALLOC(); + goto str_index_dim; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index_dim; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); + hval = Z_RES_HANDLE_P(offset); + goto num_index_dim; + } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + key = ZSTR_EMPTY_ALLOC(); + goto str_index_dim; + } else { + zend_illegal_array_offset_unset(offset); + } + break; + } else if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto unset_dim_array; + } + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + container = ZVAL_UNDEFINED_OP1(); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + offset = ZVAL_UNDEFINED_OP2(); + } + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; + } + Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset); + } else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { + zend_throw_error(NULL, "Cannot unset string offsets"); + } else if (UNEXPECTED(Z_TYPE_P(container) > IS_FALSE)) { + zend_throw_error(NULL, "Cannot unset offset in a non-array variable"); + } else if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) { + zend_false_to_array_deprecated(); + } + } while (0); + + + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DISCARD_EXCEPTION_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *fast_call = EX_VAR(opline->op1.var); - SAVE_OPLINE(); - - /* cleanup incomplete RETURN statement */ - if (Z_OPLINE_NUM_P(fast_call) != (uint32_t)-1 - && (EX(func)->op_array.opcodes[Z_OPLINE_NUM_P(fast_call)].op2_type & (IS_TMP_VAR | IS_VAR))) { - zval *return_value = EX_VAR(EX(func)->op_array.opcodes[Z_OPLINE_NUM_P(fast_call)].op2.var); + zval *container; + zval *offset; + zend_string *name, *tmp_name; + + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + + do { + if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + if (Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (Z_TYPE_P(container) != IS_OBJECT) { + if (IS_CV == IS_CV + && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + break; + } + } else { + break; + } + } + if (IS_CV == IS_CONST) { + name = Z_STR_P(offset); + } else { + name = zval_try_get_tmp_string(offset, &tmp_name); + if (UNEXPECTED(!name)) { + break; + } + } + Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + } while (0); + - zval_ptr_dtor(return_value); - } - /* cleanup delayed exception */ - if (Z_OBJ_P(fast_call) != NULL) { - /* discard the previously thrown exception */ - OBJ_RELEASE(Z_OBJ_P(fast_call)); - Z_OBJ_P(fast_call) = NULL; - } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CALL_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *fast_call = EX_VAR(opline->result.var); + zval *container; + bool result; + zend_ulong hval; + zval *offset; - Z_OBJ_P(fast_call) = NULL; - /* set return address */ - Z_OPLINE_NUM_P(fast_call) = opline - EX(func)->op_array.opcodes; - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op1), 0); -} + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + offset = EX_VAR(opline->op2.var); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_RET_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *fast_call = EX_VAR(opline->op1.var); - uint32_t current_try_catch_offset, current_op_num; + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + zval *value; + zend_string *str; - if (Z_OPLINE_NUM_P(fast_call) != (uint32_t)-1) { - const zend_op *fast_ret = EX(func)->op_array.opcodes + Z_OPLINE_NUM_P(fast_call); +isset_dim_obj_array: + ht = Z_ARRVAL_P(container); +isset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_CV != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_prop; + } + } + value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_prop: + value = zend_hash_index_find(ht, hval); + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + offset = Z_REFVAL_P(offset); + goto isset_again; + } else { + value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); + if (UNEXPECTED(EG(exception))) { + result = 0; + goto isset_dim_obj_exit; + } + } - ZEND_VM_JMP_EX(fast_ret + 1, 0); - } + if (!(opline->extended_value & ZEND_ISEMPTY)) { + /* > IS_NULL means not IS_UNDEF and not IS_NULL */ + result = value != NULL && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - /* special case for unhandled exceptions */ - EG(exception) = Z_OBJ_P(fast_call); - Z_OBJ_P(fast_call) = NULL; - current_try_catch_offset = opline->op2.num; - current_op_num = opline - EX(func)->op_array.opcodes; - ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX current_try_catch_offset, current_op_num)); -} + if (IS_CV & (IS_CONST|IS_CV)) { + /* avoid exception check */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSERT_CHECK_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - if (EG(assertions) <= 0) { - zend_op *target = OP_JMP_ADDR(opline, opline->op2); - if (RETURN_VALUE_USED(opline)) { - ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_SMART_BRANCH(result, 0); + } + } else { + result = (value == NULL || !i_zend_is_true(value)); } - ZEND_VM_JMP_EX(target, 0); + goto isset_dim_obj_exit; + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto isset_dim_obj_array; + } + } + + if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; + } + if (!(opline->extended_value & ZEND_ISEMPTY)) { + result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); } else { - ZEND_VM_NEXT_OPCODE(); + result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); } -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CALL_TRAMPOLINE_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zend_array *args = NULL; - zend_function *fbc = EX(func); - zval *ret = EX(return_value); - uint32_t call_info = EX_CALL_INFO() & (ZEND_CALL_NESTED | ZEND_CALL_TOP | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_EXTRA_NAMED_PARAMS); - uint32_t num_args = EX_NUM_ARGS(); - zend_execute_data *call; +isset_dim_obj_exit: - SAVE_OPLINE(); - if (num_args) { - zval *p = ZEND_CALL_ARG(execute_data, 1); - zval *end = p + num_args; - args = zend_new_array(num_args); - zend_hash_real_init_packed(args); - ZEND_HASH_FILL_PACKED(args) { - do { - ZEND_HASH_FILL_ADD(p); - p++; - } while (p != end); - } ZEND_HASH_FILL_END(); - } - call = execute_data; - execute_data = EG(current_execute_data) = EX(prev_execute_data); + ZEND_VM_SMART_BRANCH(result, 1); +} - call->func = (fbc->op_array.fn_flags & ZEND_ACC_STATIC) ? fbc->op_array.scope->__callstatic : fbc->op_array.scope->__call; - ZEND_ASSERT(zend_vm_calc_used_stack(2, call->func) <= (size_t)(((char*)EG(vm_stack_end)) - (char*)call)); - ZEND_CALL_NUM_ARGS(call) = 2; +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + int result; + zval *offset; + zend_string *name, *tmp_name; - ZVAL_STR(ZEND_CALL_ARG(call, 1), fbc->common.function_name); + SAVE_OPLINE(); + container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - zval *call_args = ZEND_CALL_ARG(call, 2); - if (args) { - ZVAL_ARR(call_args, args); - } else { - ZVAL_EMPTY_ARRAY(call_args); - } - if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { - if (zend_hash_num_elements(Z_ARRVAL_P(call_args)) == 0) { - GC_ADDREF(call->extra_named_params); - ZVAL_ARR(call_args, call->extra_named_params); + if (IS_CV == IS_CONST || + (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } } else { - SEPARATE_ARRAY(call_args); - zend_hash_copy(Z_ARRVAL_P(call_args), call->extra_named_params, zval_add_ref); + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } - zend_free_trampoline(fbc); - fbc = call->func; - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { - if (UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); + if (IS_CV == IS_CONST) { + name = Z_STR_P(offset); + } else { + name = zval_try_get_tmp_string(offset, &tmp_name); + if (UNEXPECTED(!name)) { + result = 0; + goto isset_object_finish; } - execute_data = call; - i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); - if (EXPECTED(zend_execute_ex == execute_ex)) { - LOAD_OPLINE_EX(); - - + } + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - ZEND_VM_ENTER_EX(); - } else { - SAVE_OPLINE_EX(); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } +isset_object_finish: - execute_data = EX(prev_execute_data); - if (execute_data) { - LOAD_OPLINE(); - } - ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); - zend_execute_ex(call); - } - } else { - zval retval; - ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); - EG(current_execute_data) = call; -#if ZEND_DEBUG - bool should_throw = zend_internal_call_should_throw(fbc, call); -#endif + ZEND_VM_SMART_BRANCH(result, 1); +} - if (ret == NULL) { - ret = &retval; - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE - ZVAL_NULL(ret); + zval *key, *subject; + HashTable *ht; + bool result; + SAVE_OPLINE(); - if (!zend_execute_internal) { - /* saves one function call if zend_execute_internal is not used */ - fbc->internal_function.handler(call, ret); - } else { - zend_execute_internal(call, ret); - } + key = EX_VAR(opline->op1.var); + subject = EX_VAR(opline->op2.var); -#if ZEND_DEBUG - if (!EG(exception) && call->func) { - if (should_throw) { - zend_internal_call_arginfo_violation(call->func); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: + ht = Z_ARRVAL_P(subject); + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); + } else { + if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; } - ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, ret)); - ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) - ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); - zend_verify_internal_func_info(call->func, ret); - } -#endif - - - EG(current_execute_data) = call->prev_execute_data; - - zend_vm_stack_free_args(call); - if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { - zend_free_extra_named_params(call->extra_named_params); - } - if (ret == &retval) { - zval_ptr_dtor(ret); } + zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); + result = 0; } - execute_data = EG(current_execute_data); - - if (!execute_data || !EX(func) || !ZEND_USER_CODE(EX(func)->type) || (call_info & ZEND_CALL_TOP)) { - ZEND_VM_RETURN(); - } - if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { - zend_object *object = Z_OBJ(call->This); - OBJ_RELEASE(object); - } - zend_vm_stack_free_call_frame(call); - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - HANDLE_EXCEPTION_LEAVE(); - } - LOAD_OPLINE(); - ZEND_VM_INC_OPCODE(); - ZEND_VM_LEAVE(); + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zend_array *args = NULL; - zend_function *fbc = EX(func); - zval *ret = EX(return_value); - uint32_t call_info = EX_CALL_INFO() & (ZEND_CALL_NESTED | ZEND_CALL_TOP | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_EXTRA_NAMED_PARAMS); - uint32_t num_args = EX_NUM_ARGS(); - zend_execute_data *call; - - SAVE_OPLINE(); + USE_OPLINE - if (num_args) { - zval *p = ZEND_CALL_ARG(execute_data, 1); - zval *end = p + num_args; + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - args = zend_new_array(num_args); - zend_hash_real_init_packed(args); - ZEND_HASH_FILL_PACKED(args) { - do { - ZEND_HASH_FILL_ADD(p); - p++; - } while (p != end); - } ZEND_HASH_FILL_END(); + SAVE_OPLINE(); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - call = execute_data; - execute_data = EG(current_execute_data) = EX(prev_execute_data); + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); - call->func = (fbc->op_array.fn_flags & ZEND_ACC_STATIC) ? fbc->op_array.scope->__callstatic : fbc->op_array.scope->__call; - ZEND_ASSERT(zend_vm_calc_used_stack(2, call->func) <= (size_t)(((char*)EG(vm_stack_end)) - (char*)call)); - ZEND_CALL_NUM_ARGS(call) = 2; + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); - ZVAL_STR(ZEND_CALL_ARG(call, 1), fbc->common.function_name); + /* Set the new yielded value */ + if (IS_CV != IS_UNUSED) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_CV & (IS_CONST|IS_TMP_VAR)) { + zval *value; - zval *call_args = ZEND_CALL_ARG(call, 2); - if (args) { - ZVAL_ARR(call_args, args); - } else { - ZVAL_EMPTY_ARRAY(call_args); - } - if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { - if (zend_hash_num_elements(Z_ARRVAL_P(call_args)) == 0) { - GC_ADDREF(call->extra_named_params); - ZVAL_ARR(call_args, call->extra_named_params); - } else { - SEPARATE_ARRAY(call_args); - zend_hash_copy(Z_ARRVAL_P(call_args), call->extra_named_params, zval_add_ref); - } - } - zend_free_trampoline(fbc); - fbc = call->func; + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { - if (UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - execute_data = call; - i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); - if (EXPECTED(zend_execute_ex == execute_ex)) { - LOAD_OPLINE_EX(); - SAVE_OPLINE(); - zend_observer_fcall_begin_specialized(execute_data, false); - ZEND_VM_ENTER_EX(); - } else { - SAVE_OPLINE_EX(); - zend_observer_fcall_begin_specialized(execute_data, false); - execute_data = EX(prev_execute_data); - if (execute_data) { - LOAD_OPLINE(); - } - ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); - zend_execute_ex(call); - } - } else { - zval retval; + value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } + } else { + zval *value_ptr = _get_zval_ptr_cv_BP_VAR_W(opline->op1.var EXECUTE_DATA_CC); - ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + do { + if (IS_CV == IS_VAR) { + ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION + && !Z_ISREF_P(value_ptr)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + ZVAL_COPY(&generator->value, value_ptr); + break; + } + } + if (Z_ISREF_P(value_ptr)) { + Z_ADDREF_P(value_ptr); + } else { + ZVAL_MAKE_REF_EX(value_ptr, 2); + } + ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); + } while (0); - EG(current_execute_data) = call; -#if ZEND_DEBUG - bool should_throw = zend_internal_call_should_throw(fbc, call); -#endif + } + } else { + zval *value = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - if (ret == NULL) { - ret = &retval; - } + /* Consts, temporary variables and references need copying */ + if (IS_CV == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } else if (IS_CV == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - ZVAL_NULL(ret); - zend_observer_fcall_begin_specialized(call, false); - if (!zend_execute_internal) { - /* saves one function call if zend_execute_internal is not used */ - fbc->internal_function.handler(call, ret); - } else { - zend_execute_internal(call, ret); - } -#if ZEND_DEBUG - if (!EG(exception) && call->func) { - if (should_throw) { - zend_internal_call_arginfo_violation(call->func); + } else { + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CV == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } } - ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || - zend_verify_internal_return_type(call->func, ret)); - ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) - ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); - zend_verify_internal_func_info(call->func, ret); } -#endif - zend_observer_fcall_end(call, EG(exception) ? NULL : ret); - - EG(current_execute_data) = call->prev_execute_data; + } else { + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); + } - zend_vm_stack_free_args(call); - if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { - zend_free_extra_named_params(call->extra_named_params); - } - if (ret == &retval) { - zval_ptr_dtor(ret); + /* Set the new yielded key */ + if (IS_CV != IS_UNUSED) { + zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + if ((IS_CV & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + key = Z_REFVAL_P(key); } - } + ZVAL_COPY(&generator->key, key); - execute_data = EG(current_execute_data); - if (!execute_data || !EX(func) || !ZEND_USER_CODE(EX(func)->type) || (call_info & ZEND_CALL_TOP)) { - ZEND_VM_RETURN(); + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); + } + } else { + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); } - if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { - zend_object *object = Z_OBJ(call->This); - OBJ_RELEASE(object); + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; } - zend_vm_stack_free_call_frame(call); - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - HANDLE_EXCEPTION_LEAVE(); - } + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); - LOAD_OPLINE(); - ZEND_VM_INC_OPCODE(); - ZEND_VM_LEAVE(); + ZEND_VM_RETURN(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + /* This is declared below the specializations for MAY_BE_LONG/MAY_BE_DOUBLE so those will be used instead if possible. */ + /* This optimizes $x === SOME_CONST_EXPR and $x === $y for non-refs and non-undef, which can't throw. */ + /* (Infinite recursion when comparing arrays is an uncatchable fatal error) */ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = fast_is_identical_function(op1, op2); + /* Free is a no-op for const/cv */ + ZEND_VM_SMART_BRANCH(result, 0); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = fast_is_identical_function(op1, op2); + /* Free is a no-op for const/cv */ + ZEND_VM_SMART_BRANCH(!result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_2_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + SAVE_OPLINE(); + zend_error_noreturn(E_ERROR, "Invalid opcode %d/%d/%d.", OPLINE->opcode, OPLINE->op1_type, OPLINE->op2_type); + ZEND_VM_NEXT_OPCODE(); /* Never reached */ +} - zval *result = EX_VAR(opline->result.var); - ZVAL_NULL(result); - zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R); - zval *arg2 = get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R); - if (EG(exception)) { - FREE_OP(opline->op1_type, opline->op1.var); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } -#if 0 || 0 - if (0 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) { - zend_frameless_observed_call(execute_data); - } else +#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) +# undef ZEND_VM_TAIL_CALL +# undef ZEND_VM_CONTINUE +# undef ZEND_VM_RETURN + +# define ZEND_VM_TAIL_CALL(call) call; ZEND_VM_CONTINUE() +# define ZEND_VM_CONTINUE() HYBRID_NEXT() +# define ZEND_VM_RETURN() goto HYBRID_HALT_LABEL #endif - { - zend_frameless_function_2 function = (zend_frameless_function_2)ZEND_FLF_HANDLER(opline); - function(result, arg1, arg2); - } - FREE_OP(opline->op1_type, opline->op1.var); - /* Set OP1 to UNDEF in case FREE_OP(opline->op2_type, opline->op2.var) throws. */ - if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { - ZVAL_UNDEF(EX_VAR(opline->op1.var)); - } - FREE_OP(opline->op2_type, opline->op2.var); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} +#if ZEND_VM_KIND == ZEND_VM_KIND_TAILCALL -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_2_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - SAVE_OPLINE(); +# undef ZEND_VM_TAIL_CALL +# undef ZEND_VM_CONTINUE +# undef ZEND_VM_RETURN +# undef ZEND_VM_DISPATCH_TO_HELPER +# undef ZEND_VM_INTERRUPT - zval *result = EX_VAR(opline->result.var); - ZVAL_NULL(result); - zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R); - zval *arg2 = get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R); - if (EG(exception)) { - FREE_OP(opline->op1_type, opline->op1.var); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } +# define ZEND_VM_TAIL_CALL(call) ZEND_MUSTTAIL return call +# define ZEND_VM_CONTINUE() ZEND_VM_TAIL_CALL(opline->handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)) +# define ZEND_VM_RETURN() opline = &call_halt_op; ZEND_VM_CONTINUE() +# define ZEND_VM_DISPATCH_TO_HELPER(call) \ + do { \ + opline = call; \ + ZEND_VM_TAIL_CALL(opline->handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); \ + } while (0) +# define ZEND_VM_DISPATCH_TO_LEAVE_HELPER(helper) opline = &call_leave_op; SAVE_OPLINE(); ZEND_VM_CONTINUE() +# define ZEND_VM_INTERRUPT() ZEND_VM_TAIL_CALL(zend_interrupt_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)) -#if 0 || 1 - if (1 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) { - zend_frameless_observed_call(execute_data); - } else -#endif - { - zend_frameless_function_2 function = (zend_frameless_function_2)ZEND_FLF_HANDLER(opline); - function(result, arg1, arg2); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_HALT_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS); +static zend_never_inline const zend_op *ZEND_OPCODE_HANDLER_CCONV zend_leave_helper_SPEC_TAILCALL(zend_execute_data *ex, const zend_op *opline); - FREE_OP(opline->op1_type, opline->op1.var); - /* Set OP1 to UNDEF in case FREE_OP(opline->op2_type, opline->op2.var) throws. */ - if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { - ZVAL_UNDEF(EX_VAR(opline->op1.var)); - } - FREE_OP(opline->op2_type, opline->op2.var); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} +static const zend_op call_halt_op = { + .handler = ZEND_HALT_TAILCALL_HANDLER, +}; +static const zend_op call_leave_op = { + .handler = zend_leave_helper_SPEC_TAILCALL, +}; -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_3_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_sub_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_mul_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_mod_by_zero_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + SAVE_OPLINE(); + zend_throw_exception_ex(zend_ce_division_by_zero_error, 0, "Modulo by zero"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); +} - zval *result = EX_VAR(opline->result.var); - ZVAL_NULL(result); - zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R); - zval *arg2 = get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R); - zval *arg3 = get_op_data_zval_ptr_deref_r((opline+1)->op1_type, (opline+1)->op1); - if (EG(exception)) { - FREE_OP(opline->op1_type, opline->op1.var); - FREE_OP(opline->op2_type, opline->op2.var); - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - HANDLE_EXCEPTION(); - } +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_mod_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_shift_left_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_shift_right_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_bw_or_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_bw_and_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_bw_xor_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_bw_not_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1); +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_this_not_in_object_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE -#if 0 || 0 - if (0 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) { - zend_frameless_observed_call(execute_data); - } else -#endif - { - zend_frameless_function_3 function = (zend_frameless_function_3)ZEND_FLF_HANDLER(opline); - function(result, arg1, arg2, arg3); - } + SAVE_OPLINE(); + zend_throw_error(NULL, "Using $this when not in object context"); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); +} - FREE_OP(opline->op1_type, opline->op1.var); - /* Set to UNDEF in case FREE_OP(opline->op2_type, opline->op2.var) throws. */ - if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { - ZVAL_UNDEF(EX_VAR(opline->op1.var)); - } - FREE_OP(opline->op2_type, opline->op2.var); - if (opline->op2_type & (IS_VAR|IS_TMP_VAR)) { - ZVAL_UNDEF(EX_VAR(opline->op2.var)); - } - FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); - ZEND_VM_NEXT_OPCODE_EX(1, 2); +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_undefined_function_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + + SAVE_OPLINE(); + function_name = RT_CONSTANT(opline, opline->op2); + zend_throw_error(NULL, "Call to undefined function %s()", Z_STRVAL_P(function_name)); + HANDLE_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_STATIC_PROP_OP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + /* 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 */ + USE_OPLINE + zval *prop, *value; + zend_property_info *prop_info; + zend_reference *ref; + SAVE_OPLINE(); - zval *result = EX_VAR(opline->result.var); - ZVAL_NULL(result); - zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R); - zval *arg2 = get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R); - zval *arg3 = get_op_data_zval_ptr_deref_r((opline+1)->op1_type, (opline+1)->op1); - if (EG(exception)) { - FREE_OP(opline->op1_type, opline->op1.var); - FREE_OP(opline->op2_type, opline->op2.var); + prop = zend_fetch_static_property_address(&prop_info, (opline+1)->extended_value, BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(!prop)) { + UNDEF_RESULT(); FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); HANDLE_EXCEPTION(); } -#if 0 || 1 - if (1 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) { - zend_frameless_observed_call(execute_data); - } else -#endif - { - zend_frameless_function_3 function = (zend_frameless_function_3)ZEND_FLF_HANDLER(opline); - function(result, arg1, arg2, arg3); + if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK) + && UNEXPECTED(!zend_asymmetric_property_has_set_access(prop_info))) { + zend_asymmetric_visibility_property_modification_error(prop_info, "indirectly modify"); + UNDEF_RESULT(); + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + HANDLE_EXCEPTION(); } - FREE_OP(opline->op1_type, opline->op1.var); - /* Set to UNDEF in case FREE_OP(opline->op2_type, opline->op2.var) throws. */ - if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { - ZVAL_UNDEF(EX_VAR(opline->op1.var)); - } - FREE_OP(opline->op2_type, opline->op2.var); - if (opline->op2_type & (IS_VAR|IS_TMP_VAR)) { - ZVAL_UNDEF(EX_VAR(opline->op2.var)); + value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); + + do { + if (UNEXPECTED(Z_ISREF_P(prop))) { + ref = Z_REF_P(prop); + prop = Z_REFVAL_P(prop); + if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { + zend_binary_assign_op_typed_ref(ref, value OPLINE_CC EXECUTE_DATA_CC); + break; + } + } + + if (ZEND_TYPE_IS_SET(prop_info->type)) { + /* special case for typed properties */ + zend_binary_assign_op_typed_prop(prop_info, prop, value OPLINE_CC EXECUTE_DATA_CC); + } else { + zend_binary_op(prop, prop, value OPLINE_CC); + } + } while (0); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), prop); } + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + /* assign_static_prop has two opcodes! */ ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_FORWARD_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_STATIC_PROP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *prop; + zend_property_info *prop_info; - OPLINE = OP_JMP_ADDR(opline, opline->op1); - ZEND_VM_CONTINUE(); -} - -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) -{ - zend_atomic_bool_store_ex(&EG(vm_interrupt), false); SAVE_OPLINE(); - if (zend_atomic_bool_load_ex(&EG(timed_out))) { - zend_timeout(); - } else if (zend_interrupt_function) { - zend_interrupt_function(execute_data); - if (EG(exception)) { - /* We have to UNDEF result, because ZEND_HANDLE_EXCEPTION is going to free it */ - const zend_op *throw_op = EG(opline_before_exception); - - if (throw_op - && throw_op->result_type & (IS_TMP_VAR|IS_VAR) - && throw_op->opcode != ZEND_ADD_ARRAY_ELEMENT - && throw_op->opcode != ZEND_ADD_ARRAY_UNPACK - && throw_op->opcode != ZEND_ROPE_INIT - && throw_op->opcode != ZEND_ROPE_ADD) { - ZVAL_UNDEF(ZEND_CALL_VAR(EG(current_execute_data), throw_op->result.var)); - } - } - ZEND_VM_ENTER(); + prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(!prop)) { + UNDEF_RESULT(); + HANDLE_EXCEPTION(); } - ZEND_VM_CONTINUE(); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_function *fbc; - zval *function_name, *func; - zend_execute_data *call; - fbc = CACHED_PTR(opline->result.num); - if (UNEXPECTED(fbc == NULL)) { - function_name = (zval*)RT_CONSTANT(opline, opline->op2); - func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(function_name+1)); - if (UNEXPECTED(func == NULL)) { - ZEND_VM_TAIL_CALL(zend_undefined_function_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - fbc = Z_FUNC_P(func); - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - CACHE_PTR(opline->result.num, fbc); + if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK) + && UNEXPECTED(!zend_asymmetric_property_has_set_access(prop_info))) { + zend_asymmetric_visibility_property_modification_error(prop_info, "indirectly modify"); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); } - call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, NULL); - call->prev_execute_data = EX(call); - EX(call) = call; - ZEND_VM_NEXT_OPCODE(); + zend_pre_incdec_property_zval(prop, + ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_STATIC_PROP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zend_execute_data *call; + zval *prop; + zend_property_info *prop_info; SAVE_OPLINE(); - function_name = RT_CONSTANT(opline, opline->op2); -try_function_name: - if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - call = zend_init_dynamic_call_string(Z_STR_P(function_name), opline->extended_value); - } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT)) { - call = zend_init_dynamic_call_object(Z_OBJ_P(function_name), opline->extended_value); - } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY)) { - call = zend_init_dynamic_call_array(Z_ARRVAL_P(function_name), opline->extended_value); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(function_name) == IS_REFERENCE)) { - function_name = Z_REFVAL_P(function_name); - goto try_function_name; - } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - function_name = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Value of type %s is not callable", - zend_zval_type_name(function_name)); - call = NULL; + prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(!prop)) { + UNDEF_RESULT(); + HANDLE_EXCEPTION(); } - if (IS_CONST & (IS_VAR|IS_TMP_VAR)) { - - - if (UNEXPECTED(EG(exception))) { - if (call) { - if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { - zend_string_release_ex(call->func->common.function_name, 0); - zend_free_trampoline(call->func); - } - zend_vm_stack_free_call_frame(call); - } - HANDLE_EXCEPTION(); - } - } else if (!call) { + if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK) + && UNEXPECTED(!zend_asymmetric_property_has_set_access(prop_info))) { + zend_asymmetric_visibility_property_modification_error(prop_info, "indirectly modify"); + UNDEF_RESULT(); HANDLE_EXCEPTION(); } - call->prev_execute_data = EX(call); - EX(call) = call; + zend_post_incdec_property_zval(prop, + ZEND_TYPE_IS_SET(prop_info->type) ? prop_info : NULL OPLINE_CC EXECUTE_DATA_CC); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX int type); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_R_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zval *func_name; - zval *func; - zend_function *fbc; - zend_execute_data *call; + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R)); +} - fbc = CACHED_PTR(opline->result.num); - if (UNEXPECTED(fbc == NULL)) { - func_name = (zval *)RT_CONSTANT(opline, opline->op2); - func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(func_name + 1)); - if (func == NULL) { - func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(func_name + 2)); - if (UNEXPECTED(func == NULL)) { - ZEND_VM_TAIL_CALL(zend_undefined_function_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - } - fbc = Z_FUNC_P(func); - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - CACHE_PTR(opline->result.num, fbc); - } +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_W_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W)); +} - call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, NULL); - call->prev_execute_data = EX(call); - EX(call) = call; +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_RW_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW)); +} - ZEND_VM_NEXT_OPCODE(); +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_FUNC_ARG_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + ZEND_VM_TAIL_CALL(ZEND_FETCH_STATIC_PROP_W_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZEND_VM_TAIL_CALL(ZEND_FETCH_STATIC_PROP_R_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_FCALL_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_UNSET_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zval *fname; - zval *func; - zend_function *fbc; - zend_execute_data *call; + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET)); +} - fbc = CACHED_PTR(opline->result.num); - if (UNEXPECTED(fbc == NULL)) { - fname = (zval*)RT_CONSTANT(opline, opline->op2); - func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(fname)); - ZEND_ASSERT(func != NULL && "Function existence must be checked at compile time"); - fbc = Z_FUNC_P(func); - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - CACHE_PTR(opline->result.num, fbc); - } +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_STATIC_PROP_IS_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS)); +} - call = _zend_vm_stack_push_call_frame_ex( - opline->op1.num, ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, NULL); - call->prev_execute_data = EX(call); - EX(call) = call; +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use temporary expression in write context"); + FREE_OP(opline->op2_type, opline->op2.var); + FREE_OP(opline->op1_type, opline->op1.var); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_FCALL_OFFSET_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_function *fbc; - zend_execute_data *call; - fbc = CACHED_PTR(opline->result.num); - if (UNEXPECTED(fbc == NULL)) { - fbc = Z_PTR(EG(function_table)->arData[Z_EXTRA_P(RT_CONSTANT(opline, opline->op2))].val); - CACHE_PTR(opline->result.num, fbc); - } - call = _zend_vm_stack_push_call_frame_ex( - opline->op1.num, ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, NULL); - call->prev_execute_data = EX(call); - EX(call) = call; - ZEND_VM_NEXT_OPCODE(); + + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use [] for reading"); + FREE_OP(opline->op2_type, opline->op2.var); + FREE_OP(opline->op1_type, opline->op1.var); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RECV_INIT_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - uint32_t arg_num; - zval *param; + zval *prop, *value; + zend_property_info *prop_info; + zend_refcounted *garbage = NULL; - ZEND_VM_REPEATABLE_OPCODE + SAVE_OPLINE(); - arg_num = opline->op1.num; - param = EX_VAR(opline->result.var); - if (arg_num > EX_NUM_ARGS()) { - zval *default_value = RT_CONSTANT(opline, opline->op2); + prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(!prop)) { + + + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + + value = RT_CONSTANT((opline+1), (opline+1)->op1); + + if (ZEND_TYPE_IS_SET(prop_info->type)) { + value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC); - if (Z_OPT_TYPE_P(default_value) == IS_CONSTANT_AST) { - zval *cache_val = (zval*)CACHE_ADDR(Z_CACHE_SLOT_P(default_value)); - /* we keep in cache only not refcounted values */ - if (Z_TYPE_P(cache_val) != IS_UNDEF) { - ZVAL_COPY_VALUE(param, cache_val); - } else { - SAVE_OPLINE(); - ZVAL_COPY(param, default_value); - zend_ast_evaluate_ctx ctx = {0}; - if (UNEXPECTED(zval_update_constant_with_ctx(param, EX(func)->op_array.scope, &ctx) != SUCCESS)) { - zval_ptr_dtor_nogc(param); - ZVAL_UNDEF(param); - HANDLE_EXCEPTION(); - } - if (!Z_REFCOUNTED_P(param) && !ctx.had_side_effects) { - ZVAL_COPY_VALUE(cache_val, param); - } - } - goto recv_init_check_type; - } else { - ZVAL_COPY(param, default_value); - } } else { -recv_init_check_type: - if ((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0) { - SAVE_OPLINE(); - if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param))) { - HANDLE_EXCEPTION(); - } - } + value = zend_assign_to_variable_ex(prop, value, IS_CONST, EX_USES_STRICT_TYPES(), &garbage); } - ZEND_VM_REPEAT_OPCODE(ZEND_RECV_INIT); - ZEND_VM_NEXT_OPCODE(); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + + /* assign_static_prop has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zend_execute_data *call; + zval *prop, *value; + zend_property_info *prop_info; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); -try_function_name: - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - call = zend_init_dynamic_call_string(Z_STR_P(function_name), opline->extended_value); - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT)) { - call = zend_init_dynamic_call_object(Z_OBJ_P(function_name), opline->extended_value); - } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY)) { - call = zend_init_dynamic_call_array(Z_ARRVAL_P(function_name), opline->extended_value); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(function_name) == IS_REFERENCE)) { - function_name = Z_REFVAL_P(function_name); - goto try_function_name; + prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(!prop)) { + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + + if (ZEND_TYPE_IS_SET(prop_info->type)) { + value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - function_name = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Value of type %s is not callable", - zend_zval_type_name(function_name)); - call = NULL; + value = zend_assign_to_variable_ex(prop, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); } - if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (UNEXPECTED(EG(exception))) { - if (call) { - if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { - zend_string_release_ex(call->func->common.function_name, 0); - zend_free_trampoline(call->func); - } - zend_vm_stack_free_call_frame(call); - } - HANDLE_EXCEPTION(); - } - } else if (!call) { - HANDLE_EXCEPTION(); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); } - call->prev_execute_data = EX(call); - EX(call) = call; + if (garbage) { + GC_DTOR_NO_REF(garbage); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + /* assign_static_prop has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RECV_SPEC_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - uint32_t arg_num = opline->op1.num; - zval *param; + zval *prop, *value; + zend_property_info *prop_info; + zend_refcounted *garbage = NULL; - if (UNEXPECTED(arg_num > EX_NUM_ARGS())) { - ZEND_VM_TAIL_CALL(zend_missing_arg_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + SAVE_OPLINE(); + + prop = zend_fetch_static_property_address(&prop_info, opline->extended_value, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(!prop)) { + + + UNDEF_RESULT(); + HANDLE_EXCEPTION(); } - param = EX_VAR(opline->result.var); + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(!(opline->op2.num & (1u << Z_TYPE_P(param))))) { - ZEND_VM_DISPATCH_TO_HELPER(zend_verify_recv_arg_type_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX param)); + if (ZEND_TYPE_IS_SET(prop_info->type)) { + value = zend_assign_to_typed_prop(prop_info, prop, value, &garbage EXECUTE_DATA_CC); + + + } else { + value = zend_assign_to_variable_ex(prop, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); } - ZEND_VM_NEXT_OPCODE(); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + + /* assign_static_prop has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RECV_VARIADIC_SPEC_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_STATIC_PROP_REF_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - uint32_t arg_num = opline->op1.num; - uint32_t arg_count = EX_NUM_ARGS(); - zval *params; + zval *prop, *value_ptr; + zend_property_info *prop_info; + zend_refcounted *garbage = NULL; SAVE_OPLINE(); - params = EX_VAR(opline->result.var); + prop = zend_fetch_static_property_address(&prop_info, opline->extended_value & ~ZEND_RETURNS_FUNCTION, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(!prop)) { + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } - if (arg_num <= arg_count) { - ZEND_ASSERT(EX(func)->common.fn_flags & ZEND_ACC_VARIADIC); - ZEND_ASSERT(EX(func)->common.num_args == arg_num - 1); - zend_arg_info *arg_info = &EX(func)->common.arg_info[arg_num - 1]; + if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK) + && UNEXPECTED(!zend_asymmetric_property_has_set_access(prop_info))) { + zend_asymmetric_visibility_property_modification_error(prop_info, "indirectly modify"); + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } - array_init_size(params, arg_count - arg_num + 1); - zend_hash_real_init_packed(Z_ARRVAL_P(params)); - ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(params)) { - zval *param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T); - if (ZEND_TYPE_IS_SET(arg_info->type)) { - ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_FREE_EXTRA_ARGS); - do { - if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param))) { - ZEND_HASH_FILL_FINISH(); - HANDLE_EXCEPTION(); - } + value_ptr = get_zval_ptr_ptr((opline+1)->op1_type, (opline+1)->op1, BP_VAR_W); - if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param); - ZEND_HASH_FILL_ADD(param); - param++; - } while (++arg_num <= arg_count); - } else { - do { - if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param); - ZEND_HASH_FILL_ADD(param); - param++; - } while (++arg_num <= arg_count); - } - } ZEND_HASH_FILL_END(); + if ((opline+1)->op1_type == IS_VAR && (opline->extended_value & ZEND_RETURNS_FUNCTION) && UNEXPECTED(!Z_ISREF_P(value_ptr))) { + if (UNEXPECTED(!zend_wrong_assign_to_variable_reference(prop, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC))) { + prop = &EG(uninitialized_zval); + } + } else if (ZEND_TYPE_IS_SET(prop_info->type)) { + prop = zend_assign_to_typed_property_reference(prop_info, prop, value_ptr, &garbage EXECUTE_DATA_CC); } else { - ZVAL_EMPTY_ARRAY(params); + zend_assign_to_variable_reference(prop, value_ptr, &garbage); } - if (EX_CALL_INFO() & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { - zend_string *name; - zval *param; - zend_arg_info *arg_info = &EX(func)->common.arg_info[EX(func)->common.num_args]; - if (ZEND_TYPE_IS_SET(arg_info->type)) { - SEPARATE_ARRAY(params); - ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(EX(extra_named_params), name, param) { - if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param))) { - HANDLE_EXCEPTION(); - } - Z_TRY_ADDREF_P(param); - zend_hash_add_new(Z_ARRVAL_P(params), name, param); - } ZEND_HASH_FOREACH_END(); - } else if (zend_hash_num_elements(Z_ARRVAL_P(params)) == 0) { - GC_ADDREF(EX(extra_named_params)); - ZVAL_ARR(params, EX(extra_named_params)); - } else { - SEPARATE_ARRAY(params); - ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(EX(extra_named_params), name, param) { - Z_TRY_ADDREF_P(param); - zend_hash_add_new(Z_ARRVAL_P(params), name, param); - } ZEND_HASH_FOREACH_END(); - } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), prop); } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + if (garbage) { + GC_DTOR(garbage); + } + + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_leave_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE + zend_execute_data *old_execute_data; + uint32_t call_info = EX_CALL_INFO(); +#if ZEND_VM_KIND != ZEND_VM_KIND_TAILCALL + /* zend_leave_helper may be called with opline=call_leave_op in TAILCALL VM */ SAVE_OPLINE(); +#endif - zval *result = EX_VAR(opline->result.var); - ZVAL_NULL(result); - zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R); - if (EG(exception)) { - FREE_OP(opline->op1_type, opline->op1.var); - HANDLE_EXCEPTION(); - } + if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP|ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_ALLOCATED|ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) == 0)) { + EG(current_execute_data) = EX(prev_execute_data); + i_free_compiled_variables(execute_data); -#if 0 || 0 - if (0 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) { - zend_frameless_observed_call(execute_data); - } else +#ifdef ZEND_PREFER_RELOAD + call_info = EX_CALL_INFO(); #endif - { - zend_frameless_function_1 function = (zend_frameless_function_1)ZEND_FLF_HANDLER(opline); - function(result, arg1); + if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { + OBJ_RELEASE(Z_OBJ(execute_data->This)); + } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { + OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); + } + EG(vm_stack_top) = (zval*)execute_data; + execute_data = EX(prev_execute_data); + + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION_LEAVE(); + } + + LOAD_NEXT_OPLINE(); + ZEND_VM_LEAVE(); + } else if (EXPECTED((call_info & (ZEND_CALL_CODE|ZEND_CALL_TOP)) == 0)) { + EG(current_execute_data) = EX(prev_execute_data); + i_free_compiled_variables(execute_data); + +#ifdef ZEND_PREFER_RELOAD + call_info = EX_CALL_INFO(); +#endif + if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { + zend_clean_and_cache_symbol_table(EX(symbol_table)); + } + + if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { + zend_free_extra_named_params(EX(extra_named_params)); + } + + /* Free extra args before releasing the closure, + * as that may free the op_array. */ + zend_vm_stack_free_extra_args_ex(call_info, execute_data); + + if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { + OBJ_RELEASE(Z_OBJ(execute_data->This)); + } else if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { + OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); + } + + old_execute_data = execute_data; + execute_data = EX(prev_execute_data); + zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); + + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION_LEAVE(); + } + + LOAD_NEXT_OPLINE(); + ZEND_VM_LEAVE(); + } else if (EXPECTED((call_info & ZEND_CALL_TOP) == 0)) { + if (EX(func)->op_array.last_var > 0) { + zend_detach_symbol_table(execute_data); + call_info |= ZEND_CALL_NEEDS_REATTACH; + } + zend_destroy_static_vars(&EX(func)->op_array); + destroy_op_array(&EX(func)->op_array); + efree_size(EX(func), sizeof(zend_op_array)); + old_execute_data = execute_data; + execute_data = EG(current_execute_data) = EX(prev_execute_data); + zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); + + if (call_info & ZEND_CALL_NEEDS_REATTACH) { + if (EX(func)->op_array.last_var > 0) { + zend_attach_symbol_table(execute_data); + } else { + ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_NEEDS_REATTACH); + } + } + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION_LEAVE(); + } + + LOAD_NEXT_OPLINE(); + ZEND_VM_LEAVE(); + } else { + if (EXPECTED((call_info & ZEND_CALL_CODE) == 0)) { + EG(current_execute_data) = EX(prev_execute_data); + i_free_compiled_variables(execute_data); +#ifdef ZEND_PREFER_RELOAD + call_info = EX_CALL_INFO(); +#endif + if (UNEXPECTED(call_info & (ZEND_CALL_HAS_SYMBOL_TABLE|ZEND_CALL_FREE_EXTRA_ARGS|ZEND_CALL_HAS_EXTRA_NAMED_PARAMS))) { + if (UNEXPECTED(call_info & ZEND_CALL_HAS_SYMBOL_TABLE)) { + zend_clean_and_cache_symbol_table(EX(symbol_table)); + } + zend_vm_stack_free_extra_args_ex(call_info, execute_data); + if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { + zend_free_extra_named_params(EX(extra_named_params)); + } + } + if (UNEXPECTED(call_info & ZEND_CALL_CLOSURE)) { + OBJ_RELEASE(ZEND_CLOSURE_OBJECT(EX(func))); + } + ZEND_VM_RETURN(); + } else /* if (call_kind == ZEND_CALL_TOP_CODE) */ { + zend_array *symbol_table = EX(symbol_table); + + if (EX(func)->op_array.last_var > 0) { + zend_detach_symbol_table(execute_data); + call_info |= ZEND_CALL_NEEDS_REATTACH; + } + if (call_info & ZEND_CALL_NEEDS_REATTACH) { + old_execute_data = EX(prev_execute_data); + while (old_execute_data) { + if (old_execute_data->func && (ZEND_CALL_INFO(old_execute_data) & ZEND_CALL_HAS_SYMBOL_TABLE)) { + if (old_execute_data->symbol_table == symbol_table) { + if (old_execute_data->func->op_array.last_var > 0) { + zend_attach_symbol_table(old_execute_data); + } else { + ZEND_ADD_CALL_FLAG(old_execute_data, ZEND_CALL_NEEDS_REATTACH); + } + } + break; + } + old_execute_data = old_execute_data->prev_execute_data; + } + } + EG(current_execute_data) = EX(prev_execute_data); + ZEND_VM_RETURN(); + } } - FREE_OP(opline->op1_type, opline->op1.var); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_1_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - SAVE_OPLINE(); - - zval *result = EX_VAR(opline->result.var); - ZVAL_NULL(result); - zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R); - if (EG(exception)) { - FREE_OP(opline->op1_type, opline->op1.var); - HANDLE_EXCEPTION(); - } -#if 0 || 1 - if (1 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) { - zend_frameless_observed_call(execute_data); - } else -#endif - { - zend_frameless_function_1 function = (zend_frameless_function_1)ZEND_FLF_HANDLER(opline); - function(result, arg1); - } - FREE_OP(opline->op1_type, opline->op1.var); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op1), 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_DYNAMIC_CALL_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zend_execute_data *call; + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; + zval retval; SAVE_OPLINE(); - function_name = EX_VAR(opline->op2.var); + EX(call) = call->prev_execute_data; -try_function_name: - if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - call = zend_init_dynamic_call_string(Z_STR_P(function_name), opline->extended_value); - } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT)) { - call = zend_init_dynamic_call_object(Z_OBJ_P(function_name), opline->extended_value); - } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY)) { - call = zend_init_dynamic_call_array(Z_ARRVAL_P(function_name), opline->extended_value); - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(function_name) == IS_REFERENCE)) { - function_name = Z_REFVAL_P(function_name); - goto try_function_name; - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - function_name = ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } + call->prev_execute_data = execute_data; + EG(current_execute_data) = call; + +#if ZEND_DEBUG + bool should_throw = zend_internal_call_should_throw(fbc, call); +#endif + + ret = 0 ? EX_VAR(opline->result.var) : &retval; + ZVAL_NULL(ret); + + + fbc->internal_function.handler(call, ret); + +#if ZEND_DEBUG + if (!EG(exception) && call->func) { + if (should_throw) { + zend_internal_call_arginfo_violation(call->func); } - zend_throw_error(NULL, "Value of type %s is not callable", - zend_zval_type_name(function_name)); - call = NULL; + ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, ret)); + ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) + ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); + zend_verify_internal_func_info(call->func, ret); } +#endif - if (IS_CV & (IS_VAR|IS_TMP_VAR)) { + ZEND_VM_FCALL_INTERRUPT_CHECK(call); - if (UNEXPECTED(EG(exception))) { - if (call) { - if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { - zend_string_release_ex(call->func->common.function_name, 0); - zend_free_trampoline(call->func); - } - zend_vm_stack_free_call_frame(call); - } - HANDLE_EXCEPTION(); + EG(current_execute_data) = execute_data; + zend_vm_stack_free_args(call); + + uint32_t call_info = ZEND_CALL_INFO(call); + if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) { + if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { + zend_free_extra_named_params(call->extra_named_params); } - } else if (!call) { - HANDLE_EXCEPTION(); + zend_vm_stack_free_call_frame_ex(call_info, call); + } else { + EG(vm_stack_top) = (zval*)call; } - call->prev_execute_data = EX(call); - EX(call) = call; + if (!0) { + i_zval_ptr_dtor(ret); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION(); + } + + ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); + ZEND_VM_CONTINUE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_NOT_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_ICALL_SPEC_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1; + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; + zval retval; - op1 = RT_CONSTANT(opline, opline->op1); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), ~Z_LVAL_P(op1)); - ZEND_VM_NEXT_OPCODE(); - } + SAVE_OPLINE(); + EX(call) = call->prev_execute_data; - ZEND_VM_DISPATCH_TO_HELPER(zend_bw_not_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1)); -} + call->prev_execute_data = execute_data; + EG(current_execute_data) = call; -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_NOT_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val; +#if ZEND_DEBUG + bool should_throw = zend_internal_call_should_throw(fbc, call); +#endif - val = RT_CONSTANT(opline, opline->op1); - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - /* The result and op1 can be the same cv zval */ - const uint32_t orig_val_type = Z_TYPE_INFO_P(val); - ZVAL_TRUE(EX_VAR(opline->result.var)); - if (IS_CONST == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - } else { - SAVE_OPLINE(); - ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val)); + ret = 1 ? EX_VAR(opline->result.var) : &retval; + ZVAL_NULL(ret); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + fbc->internal_function.handler(call, ret); + +#if ZEND_DEBUG + if (!EG(exception) && call->func) { + if (should_throw) { + zend_internal_call_arginfo_violation(call->func); + } + ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, ret)); + ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) + ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); + zend_verify_internal_func_info(call->func, ret); } - ZEND_VM_NEXT_OPCODE(); -} +#endif -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ECHO_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *z; - SAVE_OPLINE(); - z = RT_CONSTANT(opline, opline->op1); + ZEND_VM_FCALL_INTERRUPT_CHECK(call); - if (Z_TYPE_P(z) == IS_STRING) { - zend_string *str = Z_STR_P(z); + EG(current_execute_data) = execute_data; + zend_vm_stack_free_args(call); - if (ZSTR_LEN(str) != 0) { - zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); + uint32_t call_info = ZEND_CALL_INFO(call); + if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) { + if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { + zend_free_extra_named_params(call->extra_named_params); } + zend_vm_stack_free_call_frame_ex(call_info, call); } else { - zend_string *str = zval_get_string_func(z); + EG(vm_stack_top) = (zval*)call; + } - if (ZSTR_LEN(str) != 0) { - zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); - } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_string_release_ex(str, 0); + if (!1) { + i_zval_ptr_dtor(ret); } + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION(); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); + ZEND_VM_CONTINUE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPZ_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_ICALL_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; - uint8_t op1_type; + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; + zval retval; - val = RT_CONSTANT(opline, opline->op1); + SAVE_OPLINE(); + EX(call) = call->prev_execute_data; - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } + call->prev_execute_data = execute_data; + EG(current_execute_data) = call; + +#if ZEND_DEBUG + bool should_throw = zend_internal_call_should_throw(fbc, call); +#endif + + ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval; + ZVAL_NULL(ret); + + zend_observer_fcall_begin_specialized(call, false); + fbc->internal_function.handler(call, ret); + +#if ZEND_DEBUG + if (!EG(exception) && call->func) { + if (should_throw) { + zend_internal_call_arginfo_violation(call->func); } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, ret)); + ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) + ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); + zend_verify_internal_func_info(call->func, ret); } +#endif + zend_observer_fcall_end(call, EG(exception) ? NULL : ret); + ZEND_VM_FCALL_INTERRUPT_CHECK(call); - SAVE_OPLINE(); - op1_type = IS_CONST; - if (i_zend_is_true(val)) { - opline++; + EG(current_execute_data) = execute_data; + zend_vm_stack_free_args(call); + + uint32_t call_info = ZEND_CALL_INFO(call); + if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) { + if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { + zend_free_extra_named_params(call->extra_named_params); + } + zend_vm_stack_free_call_frame_ex(call_info, call); } else { - opline = OP_JMP_ADDR(opline, opline->op2); + EG(vm_stack_top) = (zval*)call; } - if (op1_type & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_nogc(val); + + if (!RETURN_VALUE_USED(opline)) { + i_zval_ptr_dtor(ret); } - ZEND_VM_JMP(opline); + + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION(); + } + + ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); + ZEND_VM_CONTINUE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPNZ_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_UCALL_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; - uint8_t op1_type; + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; - val = RT_CONSTANT(opline, opline->op1); + SAVE_OPLINE(); + EX(call) = call->prev_execute_data; - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_NEXT_OPCODE(); + ret = NULL; + if (0) { + ret = EX_VAR(opline->result.var); } - SAVE_OPLINE(); - op1_type = IS_CONST; - if (i_zend_is_true(val)) { - opline = OP_JMP_ADDR(opline, opline->op2); - } else { - opline++; - } - if (op1_type & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_nogc(val); - } - ZEND_VM_JMP(opline); + call->prev_execute_data = execute_data; + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + LOAD_OPLINE_EX(); + + + + + ZEND_VM_ENTER_EX(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPZ_EX_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_UCALL_SPEC_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; - bool ret; + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; - val = RT_CONSTANT(opline, opline->op1); + SAVE_OPLINE(); + EX(call) = call->prev_execute_data; - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + ret = NULL; + if (1) { + ret = EX_VAR(opline->result.var); } - SAVE_OPLINE(); - ret = i_zend_is_true(val); + call->prev_execute_data = execute_data; + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + LOAD_OPLINE_EX(); - if (ret) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - opline++; - } else { - ZVAL_FALSE(EX_VAR(opline->result.var)); - opline = OP_JMP_ADDR(opline, opline->op2); - } - ZEND_VM_JMP(opline); + + + ZEND_VM_ENTER_EX(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPNZ_EX_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_UCALL_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; - bool ret; + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; - val = RT_CONSTANT(opline, opline->op1); + SAVE_OPLINE(); + EX(call) = call->prev_execute_data; - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_NEXT_OPCODE(); - } + ret = NULL; + if (RETURN_VALUE_USED(opline)) { + ret = EX_VAR(opline->result.var); } + call->prev_execute_data = execute_data; + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + LOAD_OPLINE_EX(); SAVE_OPLINE(); - ret = i_zend_is_true(val); - + zend_observer_fcall_begin_specialized(execute_data, false); - if (ret) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - opline = OP_JMP_ADDR(opline, opline->op2); - } else { - ZVAL_FALSE(EX_VAR(opline->result.var)); - opline++; - } - ZEND_VM_JMP(opline); + ZEND_VM_ENTER_EX(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *retval_ptr; - zval *return_value; - + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; + zval retval; - retval_ptr = RT_CONSTANT(opline, opline->op1); - return_value = EX(return_value); + SAVE_OPLINE(); + EX(call) = call->prev_execute_data; + const uint32_t no_discard = 0 ? 0 : ZEND_ACC_NODISCARD; - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) { - SAVE_OPLINE(); - retval_ptr = ZVAL_UNDEFINED_OP1(); - if (return_value) { - ZVAL_NULL(return_value); + if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) { + if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) { + zend_deprecated_function(fbc); } - } else if (!return_value) { - if (IS_CONST & (IS_VAR|IS_TMP_VAR)) { - if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) { - SAVE_OPLINE(); - rc_dtor_func(Z_COUNTED_P(retval_ptr)); - } + if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) { + zend_nodiscard_function(fbc); } - } else { - if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) { - Z_ADDREF_P(return_value); - } - } - } else if (IS_CONST == IS_CV) { - do { - if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { - zend_refcounted *ref = Z_COUNTED_P(retval_ptr); - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (GC_MAY_LEAK(ref)) { - SAVE_OPLINE(); - gc_possible_root(ref); - } - ZVAL_NULL(retval_ptr); - break; - } else { - Z_ADDREF_P(retval_ptr); - } - } else { - retval_ptr = Z_REFVAL_P(retval_ptr); - if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } - } - } - ZVAL_COPY_VALUE(return_value, retval_ptr); - } while (0); - } else /* if (IS_CONST == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(retval_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(retval_ptr); - - retval_ptr = Z_REFVAL_P(retval_ptr); - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } - } else { - ZVAL_COPY_VALUE(return_value, retval_ptr); + if (UNEXPECTED(EG(exception) != NULL)) { + UNDEF_RESULT(); + if (!0) { + ret = &retval; + ZVAL_UNDEF(ret); } + goto fcall_by_name_end; } } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { + ret = NULL; + if (0) { + ret = EX_VAR(opline->result.var); + } + call->prev_execute_data = execute_data; + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + LOAD_OPLINE_EX(); - ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); -} + ZEND_VM_ENTER_EX(); + } else { + ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); + if (0) { + ret = NULL; + } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *retval_ptr; - zval *return_value; - zval observer_retval; + call->prev_execute_data = execute_data; + EG(current_execute_data) = call; - retval_ptr = get_zval_ptr_undef(opline->op1_type, opline->op1, BP_VAR_R); - return_value = EX(return_value); - if (!return_value) { return_value = &observer_retval; }; - if (opline->op1_type == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) { - SAVE_OPLINE(); - retval_ptr = ZVAL_UNDEFINED_OP1(); - if (return_value) { - ZVAL_NULL(return_value); - } - } else if (!return_value) { - if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { - if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) { - SAVE_OPLINE(); - rc_dtor_func(Z_COUNTED_P(retval_ptr)); +#if ZEND_DEBUG + bool should_throw = zend_internal_call_should_throw(fbc, call); +#endif + + ret = 0 ? EX_VAR(opline->result.var) : &retval; + ZVAL_NULL(ret); + + + fbc->internal_function.handler(call, ret); + +#if ZEND_DEBUG + if (!EG(exception) && call->func) { + if (should_throw) { + zend_internal_call_arginfo_violation(call->func); } + ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, ret)); + ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) + ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); + zend_verify_internal_func_info(call->func, ret); } - } else { - if ((opline->op1_type & (IS_CONST|IS_TMP_VAR))) { - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (opline->op1_type == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) { - Z_ADDREF_P(return_value); - } - } - } else if (opline->op1_type == IS_CV) { - do { - if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { - zend_refcounted *ref = Z_COUNTED_P(retval_ptr); - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (GC_MAY_LEAK(ref)) { - SAVE_OPLINE(); - gc_possible_root(ref); - } - ZVAL_NULL(retval_ptr); - break; - } else { - Z_ADDREF_P(retval_ptr); - } - } else { - retval_ptr = Z_REFVAL_P(retval_ptr); - if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } - } - } - ZVAL_COPY_VALUE(return_value, retval_ptr); - } while (0); - } else /* if (opline->op1_type == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(retval_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret)); +#endif - retval_ptr = Z_REFVAL_P(retval_ptr); - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } - } else { - ZVAL_COPY_VALUE(return_value, retval_ptr); + + ZEND_VM_FCALL_INTERRUPT_CHECK(call); + + EG(current_execute_data) = execute_data; + + goto fcall_by_name_end; + } + + if (0) { +fcall_by_name_end: + + zend_vm_stack_free_args(call); + + uint32_t call_info = ZEND_CALL_INFO(call); + if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) { + if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { + zend_free_extra_named_params(call->extra_named_params); } + zend_vm_stack_free_call_frame_ex(call_info, call); + } else { + EG(vm_stack_top) = (zval*)call; + } + + if (!0) { + i_zval_ptr_dtor(ret); } } - SAVE_OPLINE(); - zend_observer_fcall_end(execute_data, return_value); - if (return_value == &observer_retval) { zval_ptr_dtor_nogc(&observer_retval); }; - ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); + + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION(); + } + ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); + ZEND_VM_CONTINUE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_BY_REF_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *retval_ptr; - zval *return_value; - + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; + zval retval; SAVE_OPLINE(); + EX(call) = call->prev_execute_data; - return_value = EX(return_value); - - - do { - if ((IS_CONST & (IS_CONST|IS_TMP_VAR)) || - (IS_CONST == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { - /* Not supposed to happen, but we'll allow it */ - zend_error(E_NOTICE, "Only variable references should be returned by reference"); - - retval_ptr = RT_CONSTANT(opline, opline->op1); - if (!return_value) { - - - } else { - if (IS_CONST == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) { - ZVAL_COPY_VALUE(return_value, retval_ptr); - break; - } + const uint32_t no_discard = 1 ? 0 : ZEND_ACC_NODISCARD; - ZVAL_NEW_REF(return_value, retval_ptr); - if (IS_CONST == IS_CONST) { - Z_TRY_ADDREF_P(retval_ptr); - } + if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) { + if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) { + zend_deprecated_function(fbc); + } + if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) { + zend_nodiscard_function(fbc); + } + if (UNEXPECTED(EG(exception) != NULL)) { + UNDEF_RESULT(); + if (!1) { + ret = &retval; + ZVAL_UNDEF(ret); } - break; + goto fcall_by_name_end; } + } - retval_ptr = zend_get_bad_ptr(); + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { + ret = NULL; + if (1) { + ret = EX_VAR(opline->result.var); + } - if (IS_CONST == IS_VAR) { - ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) { - zend_error(E_NOTICE, "Only variable references should be returned by reference"); - if (return_value) { - ZVAL_NEW_REF(return_value, retval_ptr); - } else { + call->prev_execute_data = execute_data; + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + LOAD_OPLINE_EX(); - } - break; - } - } - if (return_value) { - if (Z_ISREF_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } else { - ZVAL_MAKE_REF_EX(retval_ptr, 2); - } - ZVAL_REF(return_value, Z_REF_P(retval_ptr)); + + ZEND_VM_ENTER_EX(); + } else { + ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); + if (0) { + ret = NULL; } + call->prev_execute_data = execute_data; + EG(current_execute_data) = call; - } while (0); +#if ZEND_DEBUG + bool should_throw = zend_internal_call_should_throw(fbc, call); +#endif + ret = 1 ? EX_VAR(opline->result.var) : &retval; + ZVAL_NULL(ret); + fbc->internal_function.handler(call, ret); - ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); -} +#if ZEND_DEBUG + if (!EG(exception) && call->func) { + if (should_throw) { + zend_internal_call_arginfo_violation(call->func); + } + ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, ret)); + ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) + ? 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 -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_BY_REF_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *retval_ptr; - zval *return_value; - zval observer_retval; - SAVE_OPLINE(); + ZEND_VM_FCALL_INTERRUPT_CHECK(call); - return_value = EX(return_value); - if (!return_value) { return_value = &observer_retval; }; - do { - if ((opline->op1_type & (IS_CONST|IS_TMP_VAR)) || - (opline->op1_type == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { - /* Not supposed to happen, but we'll allow it */ - zend_error(E_NOTICE, "Only variable references should be returned by reference"); + EG(current_execute_data) = execute_data; - retval_ptr = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R); - if (!return_value) { - FREE_OP(opline->op1_type, opline->op1.var); - } else { - if (opline->op1_type == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) { - ZVAL_COPY_VALUE(return_value, retval_ptr); - break; - } + goto fcall_by_name_end; + } - ZVAL_NEW_REF(return_value, retval_ptr); - if (opline->op1_type == IS_CONST) { - Z_TRY_ADDREF_P(retval_ptr); - } - } - break; - } + if (0) { +fcall_by_name_end: - retval_ptr = get_zval_ptr_ptr(opline->op1_type, opline->op1, BP_VAR_W); + zend_vm_stack_free_args(call); - if (opline->op1_type == IS_VAR) { - ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) { - zend_error(E_NOTICE, "Only variable references should be returned by reference"); - if (return_value) { - ZVAL_NEW_REF(return_value, retval_ptr); - } else { - FREE_OP(opline->op1_type, opline->op1.var); - } - break; + uint32_t call_info = ZEND_CALL_INFO(call); + if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) { + if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { + zend_free_extra_named_params(call->extra_named_params); } + zend_vm_stack_free_call_frame_ex(call_info, call); + } else { + EG(vm_stack_top) = (zval*)call; } - if (return_value) { - if (Z_ISREF_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } else { - ZVAL_MAKE_REF_EX(retval_ptr, 2); - } - ZVAL_REF(return_value, Z_REF_P(retval_ptr)); + if (!1) { + i_zval_ptr_dtor(ret); } + } - FREE_OP(opline->op1_type, opline->op1.var); - } while (0); - - zend_observer_fcall_end(execute_data, return_value); - if (return_value == &observer_retval) { zval_ptr_dtor_nogc(&observer_retval); }; - ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION(); + } + ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); + ZEND_VM_CONTINUE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GENERATOR_RETURN_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *retval; - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; + zval retval; SAVE_OPLINE(); - retval = RT_CONSTANT(opline, opline->op1); + EX(call) = call->prev_execute_data; - /* Copy return value into generator->retval */ - if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { - ZVAL_COPY_VALUE(&generator->retval, retval); - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) { - Z_ADDREF(generator->retval); - } - } - } else if (IS_CONST == IS_CV) { - ZVAL_COPY_DEREF(&generator->retval, retval); - } else /* if (IS_CONST == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_refcounted *ref = Z_COUNTED_P(retval); + const uint32_t no_discard = RETURN_VALUE_USED(opline) ? 0 : ZEND_ACC_NODISCARD; - retval = Z_REFVAL_P(retval); - ZVAL_COPY_VALUE(&generator->retval, retval); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(retval)) { - Z_ADDREF_P(retval); + if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) { + if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) { + zend_deprecated_function(fbc); + } + if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) { + zend_nodiscard_function(fbc); + } + if (UNEXPECTED(EG(exception) != NULL)) { + UNDEF_RESULT(); + if (!RETURN_VALUE_USED(opline)) { + ret = &retval; + ZVAL_UNDEF(ret); } - } else { - ZVAL_COPY_VALUE(&generator->retval, retval); + goto fcall_by_name_end; } } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { + ret = NULL; + if (RETURN_VALUE_USED(opline)) { + ret = EX_VAR(opline->result.var); + } - EG(current_execute_data) = EX(prev_execute_data); - - /* Close the generator to free up resources */ - zend_generator_close(generator, 1); + call->prev_execute_data = execute_data; + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + LOAD_OPLINE_EX(); + SAVE_OPLINE(); + zend_observer_fcall_begin_specialized(execute_data, false); - /* Pass execution back to handling code */ - ZEND_VM_RETURN(); -} + ZEND_VM_ENTER_EX(); + } else { + ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); + if (1) { + ret = NULL; + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GENERATOR_RETURN_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *retval; + call->prev_execute_data = execute_data; + EG(current_execute_data) = call; - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); +#if ZEND_DEBUG + bool should_throw = zend_internal_call_should_throw(fbc, call); +#endif - SAVE_OPLINE(); - retval = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R); + ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval; + ZVAL_NULL(ret); - /* Copy return value into generator->retval */ - if ((opline->op1_type & (IS_CONST|IS_TMP_VAR))) { - ZVAL_COPY_VALUE(&generator->retval, retval); - if (opline->op1_type == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) { - Z_ADDREF(generator->retval); - } - } - } else if (opline->op1_type == IS_CV) { - ZVAL_COPY_DEREF(&generator->retval, retval); - } else /* if (opline->op1_type == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_refcounted *ref = Z_COUNTED_P(retval); + zend_observer_fcall_begin_specialized(call, false); + fbc->internal_function.handler(call, ret); - retval = Z_REFVAL_P(retval); - ZVAL_COPY_VALUE(&generator->retval, retval); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(retval)) { - Z_ADDREF_P(retval); +#if ZEND_DEBUG + if (!EG(exception) && call->func) { + if (should_throw) { + zend_internal_call_arginfo_violation(call->func); } - } else { - ZVAL_COPY_VALUE(&generator->retval, retval); + ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, ret)); + ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) + ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); + zend_verify_internal_func_info(call->func, ret); } - } - - zend_observer_fcall_end(generator->execute_data, &generator->retval); - - EG(current_execute_data) = EX(prev_execute_data); + 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); - /* Close the generator to free up resources */ - zend_generator_close(generator, 1); + EG(current_execute_data) = execute_data; - /* Pass execution back to handling code */ - ZEND_VM_RETURN(); -} + goto fcall_by_name_end; + } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_THROW_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; + if (0) { +fcall_by_name_end: - SAVE_OPLINE(); - value = RT_CONSTANT(opline, opline->op1); + zend_vm_stack_free_args(call); - do { - if (IS_CONST == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - value = Z_REFVAL_P(value); - if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { - break; - } - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } + uint32_t call_info = ZEND_CALL_INFO(call); + if (UNEXPECTED(call_info & (ZEND_CALL_HAS_EXTRA_NAMED_PARAMS|ZEND_CALL_ALLOCATED))) { + if (call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { + zend_free_extra_named_params(call->extra_named_params); } - zend_throw_error(NULL, "Can only throw objects"); - - - HANDLE_EXCEPTION(); + zend_vm_stack_free_call_frame_ex(call_info, call); + } else { + EG(vm_stack_top) = (zval*)call; } - } while (0); - - zend_exception_save(); - Z_TRY_ADDREF_P(value); - zend_throw_exception_object(value); - zend_exception_restore(); + if (!RETURN_VALUE_USED(opline)) { + i_zval_ptr_dtor(ret); + } + } - HANDLE_EXCEPTION(); + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION(); + } + ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); + ZEND_VM_CONTINUE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CATCH_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_class_entry *ce, *catch_ce; - zend_object *exception; + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; + zval retval; SAVE_OPLINE(); - /* Check whether an exception has been thrown, if not, jump over code */ - zend_exception_restore(); - if (EG(exception) == NULL) { - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - catch_ce = CACHED_PTR(opline->extended_value & ~ZEND_LAST_CATCH); - if (UNEXPECTED(catch_ce == NULL)) { - catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT); - - CACHE_PTR(opline->extended_value & ~ZEND_LAST_CATCH, catch_ce); - } - ce = EG(exception)->ce; + EX(call) = call->prev_execute_data; -#ifdef HAVE_DTRACE - if (DTRACE_EXCEPTION_CAUGHT_ENABLED()) { - DTRACE_EXCEPTION_CAUGHT((char *)ce->name); - } -#endif /* HAVE_DTRACE */ + const uint32_t no_discard = 0 ? 0 : ZEND_ACC_NODISCARD; - if (ce != catch_ce) { - if (!catch_ce || !instanceof_function(ce, catch_ce)) { - if (opline->extended_value & ZEND_LAST_CATCH) { - zend_rethrow_exception(execute_data); - HANDLE_EXCEPTION(); + if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) { + if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) { + zend_deprecated_function(fbc); + } + if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) { + zend_nodiscard_function(fbc); + } + if (UNEXPECTED(EG(exception) != NULL)) { + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) { + OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func)); } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + UNDEF_RESULT(); + if (!0) { + ret = &retval; + ZVAL_UNDEF(ret); + } + goto fcall_end; } } - exception = EG(exception); - EG(exception) = NULL; - if (RETURN_VALUE_USED(opline)) { - /* Always perform a strict assignment. There is a reasonable expectation that if you - * write "catch (Exception $e)" then $e will actually be instanceof Exception. As such, - * we should not permit coercion to string here. */ - zval tmp; - ZVAL_OBJ(&tmp, exception); - zend_assign_to_variable(EX_VAR(opline->result.var), &tmp, IS_TMP_VAR, /* strict */ 1); - } else { - OBJ_RELEASE(exception); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { + ret = NULL; + if (0) { + ret = EX_VAR(opline->result.var); + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_USER_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *arg, *param; + call->prev_execute_data = execute_data; + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC); - SAVE_OPLINE(); + if (EXPECTED(zend_execute_ex == execute_ex)) { + LOAD_OPLINE_EX(); - arg = RT_CONSTANT(opline, opline->op1); - param = ZEND_CALL_VAR(EX(call), opline->result.var); - if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) { - zend_param_must_be_ref(EX(call)->func, opline->op2.num); - Z_TRY_ADDREF_P(arg); - ZVAL_NEW_REF(param, arg); - } else { - ZVAL_COPY(param, arg); - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val; + ZEND_VM_ENTER_EX(); + } else { + SAVE_OPLINE_EX(); - val = RT_CONSTANT(opline, opline->op1); - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - /* The result and op1 can be the same cv zval */ - const uint32_t orig_val_type = Z_TYPE_INFO_P(val); - ZVAL_FALSE(EX_VAR(opline->result.var)); - if (IS_CONST == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + execute_data = EX(prev_execute_data); + LOAD_OPLINE(); + ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); + zend_execute_ex(call); } } else { - SAVE_OPLINE(); - ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val)); + ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); + if (0) { + ret = NULL; + } + call->prev_execute_data = execute_data; + EG(current_execute_data) = call; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); -} +#if ZEND_DEBUG + bool should_throw = zend_internal_call_should_throw(fbc, call); +#endif -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CLONE_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *obj; - zend_object *zobj; - zend_class_entry *ce, *scope; - zend_function *clone; - zend_object_clone_obj_t clone_call; + ret = 0 ? EX_VAR(opline->result.var) : &retval; + ZVAL_NULL(ret); - SAVE_OPLINE(); - obj = RT_CONSTANT(opline, opline->op1); - /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. - * The OPcode intentionally does not support a clone-with property list to keep it simple. */ + if (!zend_execute_internal) { + /* saves one function call if zend_execute_internal is not used */ + fbc->internal_function.handler(call, ret); + } else { + zend_execute_internal(call, ret); + } - do { - if (IS_CONST == IS_CONST || - (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) { - obj = Z_REFVAL_P(obj); - if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) { - break; - } - } - ZVAL_UNDEF(EX_VAR(opline->result.var)); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } +#if ZEND_DEBUG + if (!EG(exception) && call->func && !(call->func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE)) { + if (should_throw) { + zend_internal_call_arginfo_violation(call->func); } - zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj)); - - - HANDLE_EXCEPTION(); + ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, ret)); + ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) + ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); + zend_verify_internal_func_info(call->func, ret); } - } while (0); + ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret)); +#endif - zobj = Z_OBJ_P(obj); - ce = zobj->ce; - clone = ce->clone; - clone_call = zobj->handlers->clone_obj; - if (UNEXPECTED(clone_call == NULL)) { - zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); + ZEND_VM_FCALL_INTERRUPT_CHECK(call); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } + EG(current_execute_data) = execute_data; - if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) { - scope = EX(func)->op_array.scope; - ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC)); - if (!zend_check_method_accessible(clone, scope)) { - zend_bad_method_call(clone, clone->common.function_name, scope); + goto fcall_end; + } + if (0) { +fcall_end: - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); + zend_vm_stack_free_args(call); + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { + zend_free_extra_named_params(call->extra_named_params); } - } - ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj)); + if (!0) { + i_zval_ptr_dtor(ret); + } + } + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) { + OBJ_RELEASE(Z_OBJ(call->This)); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + zend_vm_stack_free_call_frame(call); + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION(); + } + ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); + ZEND_VM_CONTINUE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CAST_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_SPEC_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *expr; - zval *result = EX_VAR(opline->result.var); + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; + zval retval; SAVE_OPLINE(); - expr = RT_CONSTANT(opline, opline->op1); - - switch (opline->extended_value) { - case IS_LONG: - ZVAL_LONG(result, zval_get_long(expr)); - break; - case IS_DOUBLE: - ZVAL_DOUBLE(result, zval_get_double(expr)); - break; - case IS_STRING: - ZVAL_STR(result, zval_get_string(expr)); - break; - default: - ZEND_ASSERT(opline->extended_value != _IS_BOOL && "Must use ZEND_BOOL instead"); - if (IS_CONST & (IS_VAR|IS_CV)) { - ZVAL_DEREF(expr); - } - /* If value is already of correct type, return it directly */ - if (Z_TYPE_P(expr) == opline->extended_value) { - ZVAL_COPY_VALUE(result, expr); - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_CONST != IS_TMP_VAR) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); - } + EX(call) = call->prev_execute_data; + const uint32_t no_discard = 1 ? 0 : ZEND_ACC_NODISCARD; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) { + if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) { + zend_deprecated_function(fbc); + } + if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) { + zend_nodiscard_function(fbc); + } + if (UNEXPECTED(EG(exception) != NULL)) { + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) { + OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func)); } - - if (opline->extended_value == IS_ARRAY) { - zend_cast_zval_to_array(result, expr, IS_CONST); - } else { - ZEND_ASSERT(opline->extended_value == IS_OBJECT); - zend_cast_zval_to_object(result, expr, IS_CONST); + UNDEF_RESULT(); + if (!1) { + ret = &retval; + ZVAL_UNDEF(ret); } + goto fcall_end; + } } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { + ret = NULL; + if (1) { + ret = EX_VAR(opline->result.var); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + call->prev_execute_data = execute_data; + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_op_array *new_op_array; - zval *inc_filename; + if (EXPECTED(zend_execute_ex == execute_ex)) { + LOAD_OPLINE_EX(); - SAVE_OPLINE(); - inc_filename = RT_CONSTANT(opline, opline->op1); - new_op_array = zend_include_or_eval(inc_filename, opline->extended_value); - if (UNEXPECTED(EG(exception) != NULL)) { - if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) { - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); - } - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else if (new_op_array == ZEND_FAKE_OP_ARRAY) { - if (RETURN_VALUE_USED(opline)) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - } - } else if (UNEXPECTED(new_op_array == NULL)) { - if (RETURN_VALUE_USED(opline)) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - } - } else if (new_op_array->last == 1 - && new_op_array->opcodes[0].opcode == ZEND_RETURN - && new_op_array->opcodes[0].op1_type == IS_CONST - && EXPECTED(zend_execute_ex == execute_ex)) { - if (RETURN_VALUE_USED(opline)) { - const zend_op *op = new_op_array->opcodes; - ZVAL_COPY(EX_VAR(opline->result.var), RT_CONSTANT(op, op->op1)); + ZEND_VM_ENTER_EX(); + } else { + SAVE_OPLINE_EX(); + + + execute_data = EX(prev_execute_data); + LOAD_OPLINE(); + ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); + zend_execute_ex(call); } - zend_destroy_static_vars(new_op_array); - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); } else { - zval *return_value = NULL; - zend_execute_data *call; - if (RETURN_VALUE_USED(opline)) { - return_value = EX_VAR(opline->result.var); + ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); + if (0) { + ret = NULL; } - new_op_array->scope = EX(func)->op_array.scope; + call->prev_execute_data = execute_data; + EG(current_execute_data) = call; - call = zend_vm_stack_push_call_frame( - (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, - (zend_function*)new_op_array, 0, - Z_PTR(EX(This))); +#if ZEND_DEBUG + bool should_throw = zend_internal_call_should_throw(fbc, call); +#endif - if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { - call->symbol_table = EX(symbol_table); + ret = 1 ? EX_VAR(opline->result.var) : &retval; + ZVAL_NULL(ret); + + + if (!zend_execute_internal) { + /* saves one function call if zend_execute_internal is not used */ + fbc->internal_function.handler(call, ret); } else { - call->symbol_table = zend_rebuild_symbol_table(); + zend_execute_internal(call, ret); } - call->prev_execute_data = execute_data; - i_init_code_execute_data(call, new_op_array, return_value); +#if ZEND_DEBUG + if (!EG(exception) && call->func && !(call->func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE)) { + if (should_throw) { + zend_internal_call_arginfo_violation(call->func); + } + ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, ret)); + ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) + ? 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 - if (EXPECTED(zend_execute_ex == execute_ex)) { + ZEND_VM_FCALL_INTERRUPT_CHECK(call); + EG(current_execute_data) = execute_data; - ZEND_VM_ENTER(); - } else { - ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); - zend_execute_ex(call); - zend_vm_stack_free_call_frame(call); - } + goto fcall_end; + } - zend_destroy_static_vars(new_op_array); - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); + if (0) { +fcall_end: + zend_vm_stack_free_args(call); + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { + zend_free_extra_named_params(call->extra_named_params); + } - UNDEF_RESULT(); - HANDLE_EXCEPTION(); + if (!1) { + i_zval_ptr_dtor(ret); } } + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) { + OBJ_RELEASE(Z_OBJ(call->This)); + } - ZEND_VM_NEXT_OPCODE(); + zend_vm_stack_free_call_frame(call); + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION(); + } + ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); + ZEND_VM_CONTINUE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DO_FCALL_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_op_array *new_op_array; - zval *inc_filename; + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; + zval retval; SAVE_OPLINE(); - inc_filename = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R); - new_op_array = zend_include_or_eval(inc_filename, opline->extended_value); - if (UNEXPECTED(EG(exception) != NULL)) { - FREE_OP(opline->op1_type, opline->op1.var); - if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) { - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); + EX(call) = call->prev_execute_data; + + const uint32_t no_discard = RETURN_VALUE_USED(opline) ? 0 : ZEND_ACC_NODISCARD; + + if (UNEXPECTED(fbc->common.fn_flags & (ZEND_ACC_DEPRECATED|no_discard))) { + if (fbc->common.fn_flags & ZEND_ACC_DEPRECATED) { + zend_deprecated_function(fbc); } - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else if (new_op_array == ZEND_FAKE_OP_ARRAY) { - if (RETURN_VALUE_USED(opline)) { - ZVAL_TRUE(EX_VAR(opline->result.var)); + if ((fbc->common.fn_flags & no_discard) && EG(exception) == NULL) { + zend_nodiscard_function(fbc); } - } else if (UNEXPECTED(new_op_array == NULL)) { - if (RETURN_VALUE_USED(opline)) { - ZVAL_FALSE(EX_VAR(opline->result.var)); + if (UNEXPECTED(EG(exception) != NULL)) { + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_CLOSURE)) { + OBJ_RELEASE(ZEND_CLOSURE_OBJECT(call->func)); + } + UNDEF_RESULT(); + if (!RETURN_VALUE_USED(opline)) { + ret = &retval; + ZVAL_UNDEF(ret); + } + goto fcall_end; } - } else if (new_op_array->last == 1 - && new_op_array->opcodes[0].opcode == ZEND_RETURN - && new_op_array->opcodes[0].op1_type == IS_CONST - && EXPECTED(zend_execute_ex == execute_ex)) { - if (RETURN_VALUE_USED(opline)) { - const zend_op *op = new_op_array->opcodes; + } - ZVAL_COPY(EX_VAR(opline->result.var), RT_CONSTANT(op, op->op1)); - } - zend_destroy_static_vars(new_op_array); - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); - } else { - zval *return_value = NULL; - zend_execute_data *call; + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { + ret = NULL; if (RETURN_VALUE_USED(opline)) { - return_value = EX_VAR(opline->result.var); - } - - new_op_array->scope = EX(func)->op_array.scope; - - call = zend_vm_stack_push_call_frame( - (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, - (zend_function*)new_op_array, 0, - Z_PTR(EX(This))); - - if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { - call->symbol_table = EX(symbol_table); - } else { - call->symbol_table = zend_rebuild_symbol_table(); + ret = EX_VAR(opline->result.var); } call->prev_execute_data = execute_data; - i_init_code_execute_data(call, new_op_array, return_value); - zend_observer_fcall_begin_specialized(call, false); + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 1 EXECUTE_DATA_CC); + if (EXPECTED(zend_execute_ex == execute_ex)) { - FREE_OP(opline->op1_type, opline->op1.var); - ZEND_VM_ENTER(); + LOAD_OPLINE_EX(); + SAVE_OPLINE(); + zend_observer_fcall_begin_specialized(execute_data, false); + ZEND_VM_ENTER_EX(); } else { + SAVE_OPLINE_EX(); + zend_observer_fcall_begin_specialized(execute_data, false); + execute_data = EX(prev_execute_data); + LOAD_OPLINE(); ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); zend_execute_ex(call); - zend_vm_stack_free_call_frame(call); - } - - zend_destroy_static_vars(new_op_array); - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - FREE_OP(opline->op1_type, opline->op1.var); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); } - } - FREE_OP(opline->op1_type, opline->op1.var); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_R_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *array_ptr, *result; - - SAVE_OPLINE(); - - array_ptr = RT_CONSTANT(opline, opline->op1); - if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { - result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, array_ptr); - if (IS_CONST != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(array_ptr); + } else { + ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); + if (1) { + ret = NULL; } - Z_FE_POS_P(result) = 0; - - - ZEND_VM_NEXT_OPCODE(); - } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { - zend_object *zobj = Z_OBJ_P(array_ptr); - if (!zobj->ce->get_iterator) { - if (UNEXPECTED(zend_object_is_lazy(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (UNEXPECTED(EG(exception))) { - UNDEF_RESULT(); - - HANDLE_EXCEPTION(); - } - } - HashTable *properties = zobj->properties; - if (properties) { - if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(properties); - } - properties = zobj->properties = zend_array_dup(properties); - } - } else { - properties = zobj->handlers->get_properties(zobj); - } + call->prev_execute_data = execute_data; + EG(current_execute_data) = call; - result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, array_ptr); - if (IS_CONST != IS_TMP_VAR) { - Z_ADDREF_P(array_ptr); - } +#if ZEND_DEBUG + bool should_throw = zend_internal_call_should_throw(fbc, call); +#endif - if (zend_hash_num_elements(properties) == 0) { - Z_FE_ITER_P(result) = (uint32_t) -1; + ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval; + ZVAL_NULL(ret); + zend_observer_fcall_begin_specialized(call, false); + if (!zend_execute_internal) { + /* saves one function call if zend_execute_internal is not used */ + fbc->internal_function.handler(call, ret); + } else { + zend_execute_internal(call, ret); + } - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); +#if ZEND_DEBUG + if (!EG(exception) && call->func && !(call->func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE)) { + if (should_throw) { + zend_internal_call_arginfo_violation(call->func); } + ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, ret)); + ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) + ? 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); - Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0); + EG(current_execute_data) = execute_data; + goto fcall_end; + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); + if (0) { +fcall_end: + zend_vm_stack_free_args(call); + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { + zend_free_extra_named_params(call->extra_named_params); + } - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } else if (is_empty) { - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else { - ZEND_VM_NEXT_OPCODE(); - } + if (!RETURN_VALUE_USED(opline)) { + i_zval_ptr_dtor(ret); } - } else { - zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; + } + if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) { + OBJ_RELEASE(Z_OBJ(call->This)); + } - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + zend_vm_stack_free_call_frame(call); + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION(); } + ZEND_VM_SET_OPCODE_NO_INTERRUPT(opline + 1); + ZEND_VM_CONTINUE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_RW_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GENERATOR_CREATE_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zval *array_ptr, *array_ref; + zval *return_value = EX(return_value); - SAVE_OPLINE(); + if (EXPECTED(return_value)) { + USE_OPLINE + zend_generator *generator; + zend_execute_data *gen_execute_data; + uint32_t num_args, used_stack, call_info; - if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { - array_ref = array_ptr = zend_get_bad_ptr(); - if (Z_ISREF_P(array_ref)) { - array_ptr = Z_REFVAL_P(array_ref); + SAVE_OPLINE(); + object_init_ex(return_value, zend_ce_generator); + + /* + * Normally the execute_data is allocated on the VM stack (because it does + * not actually do any allocation and thus is faster). For generators + * though this behavior would be suboptimal, because the (rather large) + * structure would have to be copied back and forth every time execution is + * suspended or resumed. That's why for generators the execution context + * is allocated on heap. + */ + num_args = EX_NUM_ARGS(); + if (EXPECTED(num_args <= EX(func)->op_array.num_args)) { + used_stack = (ZEND_CALL_FRAME_SLOT + EX(func)->op_array.last_var + EX(func)->op_array.T) * sizeof(zval); + gen_execute_data = (zend_execute_data*)emalloc(used_stack); + used_stack = (ZEND_CALL_FRAME_SLOT + EX(func)->op_array.last_var) * sizeof(zval); + } else { + used_stack = (ZEND_CALL_FRAME_SLOT + num_args + EX(func)->op_array.last_var + EX(func)->op_array.T - EX(func)->op_array.num_args) * sizeof(zval); + gen_execute_data = (zend_execute_data*)emalloc(used_stack); + } + memcpy(gen_execute_data, execute_data, used_stack); + + /* Save execution context in generator object. */ + generator = (zend_generator *) Z_OBJ_P(EX(return_value)); + generator->func = gen_execute_data->func; + generator->execute_data = gen_execute_data; + generator->frozen_call_stack = NULL; + generator->execute_fake.opline = NULL; + generator->execute_fake.func = NULL; + generator->execute_fake.prev_execute_data = NULL; + ZVAL_OBJ(&generator->execute_fake.This, (zend_object *) generator); + + gen_execute_data->opline = opline; + /* EX(return_value) keeps pointer to zend_object (not a real zval) */ + gen_execute_data->return_value = (zval*)generator; + call_info = Z_TYPE_INFO(EX(This)); + if ((call_info & Z_TYPE_MASK) == IS_OBJECT + && (!(call_info & (ZEND_CALL_CLOSURE|ZEND_CALL_RELEASE_THIS)) + /* Bug #72523 */ + || UNEXPECTED(zend_execute_ex != execute_ex))) { + ZEND_ADD_CALL_FLAG_EX(call_info, ZEND_CALL_RELEASE_THIS); + Z_ADDREF(gen_execute_data->This); + } + ZEND_ADD_CALL_FLAG_EX(call_info, (ZEND_CALL_TOP_FUNCTION | ZEND_CALL_ALLOCATED | ZEND_CALL_GENERATOR)); + Z_TYPE_INFO(gen_execute_data->This) = call_info; + gen_execute_data->prev_execute_data = NULL; + + call_info = EX_CALL_INFO(); + EG(current_execute_data) = EX(prev_execute_data); + if (EXPECTED(!(call_info & (ZEND_CALL_TOP|ZEND_CALL_ALLOCATED)))) { + EG(vm_stack_top) = (zval*)execute_data; + execute_data = EX(prev_execute_data); + LOAD_NEXT_OPLINE(); + ZEND_VM_LEAVE(); + } else if (EXPECTED(!(call_info & ZEND_CALL_TOP))) { + zend_execute_data *old_execute_data = execute_data; + execute_data = EX(prev_execute_data); + zend_vm_stack_free_call_frame_ex(call_info, old_execute_data); + LOAD_NEXT_OPLINE(); + ZEND_VM_LEAVE(); + } else { + ZEND_VM_RETURN(); } } else { - array_ref = array_ptr = RT_CONSTANT(opline, opline->op1); + ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); } +} - if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { - if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { - if (array_ptr == array_ref) { - ZVAL_NEW_REF(array_ref, array_ref); - array_ptr = Z_REFVAL_P(array_ref); - } - Z_ADDREF_P(array_ref); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); - } else { - array_ref = EX_VAR(opline->result.var); - ZVAL_NEW_REF(array_ref, array_ptr); - array_ptr = Z_REFVAL_P(array_ref); - } - if (IS_CONST == IS_CONST) { - ZVAL_ARR(array_ptr, zend_array_dup(Z_ARRVAL_P(array_ptr))); - } else { - SEPARATE_ARRAY(array_ptr); - } - Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0); +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t _arg_num, zval *_arg); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_UNPACK_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *args; + uint32_t arg_num; + + SAVE_OPLINE(); + args = get_zval_ptr_undef(opline->op1_type, opline->op1, BP_VAR_R); + arg_num = ZEND_CALL_NUM_ARGS(EX(call)) + 1; +send_again: + if (EXPECTED(Z_TYPE_P(args) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(args); + zval *arg, *top; + zend_string *name; + bool have_named_params = 0; - ZEND_VM_NEXT_OPCODE(); - } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { - if (!Z_OBJCE_P(array_ptr)->get_iterator) { - zend_object *zobj = Z_OBJ_P(array_ptr); - HashTable *properties; - if (UNEXPECTED(zend_object_is_lazy(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (UNEXPECTED(EG(exception))) { - UNDEF_RESULT(); + zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, zend_hash_num_elements(ht)); + // TODO: Speed this up using a flag that specifies whether there are any ref parameters. + if ((opline->op1_type & (IS_VAR|IS_CV)) && Z_REFCOUNT_P(args) > 1) { + uint32_t tmp_arg_num = arg_num; + bool separate = 0; - HANDLE_EXCEPTION(); + /* check if any of arguments are going to be passed by reference */ + ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) { + if (UNEXPECTED(name)) { + void *cache_slot[2] = {NULL, NULL}; + tmp_arg_num = zend_get_arg_offset_by_name( + EX(call)->func, name, cache_slot) + 1; + } + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, tmp_arg_num)) { + separate = 1; + break; } + tmp_arg_num++; + } ZEND_HASH_FOREACH_END(); + if (separate) { + SEPARATE_ARRAY(args); + ht = Z_ARRVAL_P(args); } - if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { - if (array_ptr == array_ref) { - ZVAL_NEW_REF(array_ref, array_ref); - array_ptr = Z_REFVAL_P(array_ref); + } + + ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) { + if (UNEXPECTED(name)) { + void *cache_slot[2] = {NULL, NULL}; + have_named_params = 1; + top = zend_handle_named_arg(&EX(call), name, &arg_num, cache_slot); + if (UNEXPECTED(!top)) { + FREE_OP(opline->op1_type, opline->op1.var); + HANDLE_EXCEPTION(); } - Z_ADDREF_P(array_ref); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); } else { - array_ptr = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(array_ptr, array_ref); - } - if (Z_OBJ_P(array_ptr)->properties - && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(Z_OBJ_P(array_ptr)->properties); + if (have_named_params) { + zend_throw_error(NULL, + "Cannot use positional argument after named argument during unpacking"); + FREE_OP(opline->op1_type, opline->op1.var); + HANDLE_EXCEPTION(); } - Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); - } - - properties = Z_OBJPROP_P(array_ptr); - if (zend_hash_num_elements(properties) == 0) { - Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1; + top = ZEND_CALL_ARG(EX(call), arg_num); + ZEND_CALL_NUM_ARGS(EX(call))++; + } - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + if (Z_ISREF_P(arg)) { + Z_ADDREF_P(arg); + ZVAL_REF(top, Z_REF_P(arg)); + } else if (opline->op1_type & (IS_VAR|IS_CV)) { + /* array is already separated above */ + ZVAL_MAKE_REF_EX(arg, 2); + ZVAL_REF(top, Z_REF_P(arg)); + } else { + Z_TRY_ADDREF_P(arg); + ZVAL_NEW_REF(top, arg); + } + } else { + ZVAL_COPY_DEREF(top, arg); } - Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0); + arg_num++; + } ZEND_HASH_FOREACH_END(); + } else if (EXPECTED(Z_TYPE_P(args) == IS_OBJECT)) { + zend_class_entry *ce = Z_OBJCE_P(args); + zend_object_iterator *iter; + bool have_named_params = 0; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + if (!ce || !ce->get_iterator) { + zend_type_error("Only arrays and Traversables can be unpacked, %s given", zend_zval_value_name(args)); } else { - bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); - - if (UNEXPECTED(EG(exception))) { + iter = ce->get_iterator(ce, args, 0); + if (UNEXPECTED(!iter)) { + FREE_OP(opline->op1_type, opline->op1.var); + if (!EG(exception)) { + zend_throw_exception_ex( + NULL, 0, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name) + ); + } HANDLE_EXCEPTION(); - } else if (is_empty) { - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else { - ZEND_VM_NEXT_OPCODE(); } - } - } else { - zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; - - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); - } -} + const zend_object_iterator_funcs *funcs = iter->funcs; + if (funcs->rewind) { + funcs->rewind(iter); + } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_SET_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zend_reference *ref = NULL; - bool ret; + for (; funcs->valid(iter) == SUCCESS; ++arg_num) { + zval *arg, *top; - SAVE_OPLINE(); - value = RT_CONSTANT(opline, opline->op1); + if (UNEXPECTED(EG(exception) != NULL)) { + break; + } - if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(value)) { - if (IS_CONST == IS_VAR) { - ref = Z_REF_P(value); - } - value = Z_REFVAL_P(value); - } + arg = funcs->get_current_data(iter); + if (UNEXPECTED(EG(exception) != NULL)) { + break; + } - ret = i_zend_is_true(value); + zend_string *name = NULL; + if (funcs->get_current_key) { + zval key; + funcs->get_current_key(iter, &key); + if (UNEXPECTED(EG(exception) != NULL)) { + break; + } - if (UNEXPECTED(EG(exception))) { + if (UNEXPECTED(Z_TYPE(key) != IS_LONG)) { + if (UNEXPECTED(Z_TYPE(key) != IS_STRING)) { + zend_throw_error(NULL, + "Keys must be of type int|string during argument unpacking"); + zval_ptr_dtor(&key); + break; + } + name = Z_STR_P(&key); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } + zend_ulong tmp; + if (ZEND_HANDLE_NUMERIC(name, tmp)) { + name = NULL; + } + } + } - if (ret) { - zval *result = EX_VAR(opline->result.var); + if (UNEXPECTED(name)) { + void *cache_slot[2] = {NULL, NULL}; + have_named_params = 1; + top = zend_handle_named_arg(&EX(call), name, &arg_num, cache_slot); + if (UNEXPECTED(!top)) { + zend_string_release(name); + break; + } - ZVAL_COPY_VALUE(result, value); - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_CONST == IS_CV) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); - } else if (IS_CONST == IS_VAR && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } + ZVAL_DEREF(arg); + Z_TRY_ADDREF_P(arg); + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + zend_error( + E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()" + " by unpacking a Traversable, passing by-value instead", arg_num, + EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "", + EX(call)->func->common.scope ? "::" : "", + ZSTR_VAL(EX(call)->func->common.function_name) + ); + ZVAL_NEW_REF(top, arg); + } else { + ZVAL_COPY_VALUE(top, arg); + } - ZEND_VM_NEXT_OPCODE(); -} + zend_string_release(name); + } else { + if (have_named_params) { + zend_throw_error(NULL, + "Cannot use positional argument after named argument during unpacking"); + break; + } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COALESCE_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zend_reference *ref = NULL; + zend_vm_stack_extend_call_frame(&EX(call), arg_num - 1, 1); + top = ZEND_CALL_ARG(EX(call), arg_num); + ZVAL_DEREF(arg); + Z_TRY_ADDREF_P(arg); - SAVE_OPLINE(); - value = RT_CONSTANT(opline, opline->op1); + if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + zend_error( + E_WARNING, "Cannot pass by-reference argument %d of %s%s%s()" + " by unpacking a Traversable, passing by-value instead", arg_num, + EX(call)->func->common.scope ? ZSTR_VAL(EX(call)->func->common.scope->name) : "", + EX(call)->func->common.scope ? "::" : "", + ZSTR_VAL(EX(call)->func->common.function_name) + ); + ZVAL_NEW_REF(top, arg); + } else { + ZVAL_COPY_VALUE(top, arg); + } - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - if (IS_CONST & IS_VAR) { - ref = Z_REF_P(value); - } - value = Z_REFVAL_P(value); - } + ZEND_CALL_NUM_ARGS(EX(call))++; + } - if (Z_TYPE_P(value) > IS_NULL) { - zval *result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, value); - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_CONST == IS_CV) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); - } else if ((IS_CONST & IS_VAR) && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); + funcs->move_forward(iter); } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - if ((IS_CONST & IS_VAR) && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); + zend_iterator_dtor(iter); } - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_NULL_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val, *result; - - val = RT_CONSTANT(opline, opline->op1); - - if (Z_TYPE_P(val) > IS_NULL) { - do { - if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { - val = Z_REFVAL_P(val); - if (Z_TYPE_P(val) <= IS_NULL) { - - - break; - } - } - ZEND_VM_NEXT_OPCODE(); - } while (0); - } - - result = EX_VAR(opline->result.var); - uint32_t short_circuiting_type = opline->extended_value & ZEND_SHORT_CIRCUITING_CHAIN_MASK; - if (EXPECTED(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { - ZVAL_NULL(result); - if (IS_CONST == IS_CV - && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF) - && (opline->extended_value & ZEND_JMP_NULL_BP_VAR_IS) == 0 - ) { - SAVE_OPLINE(); + } else if (EXPECTED(Z_ISREF_P(args))) { + args = Z_REFVAL_P(args); + goto send_again; + } else { + if (opline->op1_type == IS_CV && UNEXPECTED(Z_TYPE_P(args) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } } - } else if (short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { - ZVAL_FALSE(result); - } else { - ZEND_ASSERT(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); - ZVAL_TRUE(result); + zend_type_error("Only arrays and Traversables can be unpacked, %s given", zend_zval_value_name(args)); } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + FREE_OP(opline->op1_type, opline->op1.var); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_ARRAY_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - zval *result = EX_VAR(opline->result.var); + zval *args; - value = RT_CONSTANT(opline, opline->op1); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } + SAVE_OPLINE(); + args = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R); - if (IS_CONST == IS_CV) { - ZVAL_COPY_DEREF(result, value); - } else if (IS_CONST == IS_VAR) { - if (UNEXPECTED(Z_ISREF_P(value))) { - ZVAL_COPY_VALUE(result, Z_REFVAL_P(value)); - if (UNEXPECTED(Z_DELREF_P(value) == 0)) { - efree_size(Z_REF_P(value), sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); + if (UNEXPECTED(Z_TYPE_P(args) != IS_ARRAY)) { + if ((opline->op1_type & (IS_VAR|IS_CV)) && Z_ISREF_P(args)) { + args = Z_REFVAL_P(args); + if (EXPECTED(Z_TYPE_P(args) == IS_ARRAY)) { + goto send_array; } - } else { - ZVAL_COPY_VALUE(result, value); } + zend_type_error("call_user_func_array(): Argument #2 ($args) must be of type array, %s given", zend_zval_value_name(args)); + FREE_OP(opline->op2_type, opline->op2.var); + FREE_OP(opline->op1_type, opline->op1.var); + HANDLE_EXCEPTION(); } else { - ZVAL_COPY_VALUE(result, value); - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) { - Z_ADDREF_P(result); + uint32_t arg_num; + HashTable *ht; + zval *arg, *param; + +send_array: + ht = Z_ARRVAL_P(args); + if (opline->op2_type != IS_UNUSED) { + /* We don't need to handle named params in this case, + * because array_slice() is called with $preserve_keys == false. */ + zval *op2 = get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R); + uint32_t skip = opline->extended_value; + uint32_t count = zend_hash_num_elements(ht); + zend_long len; + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + len = Z_LVAL_P(op2); + } else if (Z_TYPE_P(op2) == IS_NULL) { + len = count - skip; + } else if (EX_USES_STRICT_TYPES() + || !zend_parse_arg_long_weak(op2, &len, /* arg_num */ 3)) { + zend_type_error( + "array_slice(): Argument #3 ($length) must be of type ?int, %s given", + zend_zval_value_name(op2)); + FREE_OP(opline->op2_type, opline->op2.var); + FREE_OP(opline->op1_type, opline->op1.var); + HANDLE_EXCEPTION(); + } + + if (len < 0) { + len += (zend_long)(count - skip); + } + if (skip < count && len > 0) { + if (len > (zend_long)(count - skip)) { + len = (zend_long)(count - skip); + } + zend_vm_stack_extend_call_frame(&EX(call), 0, len); + arg_num = 1; + param = ZEND_CALL_ARG(EX(call), 1); + ZEND_HASH_FOREACH_VAL(ht, arg) { + bool must_wrap = 0; + if (skip > 0) { + skip--; + continue; + } else if ((zend_long)(arg_num - 1) >= len) { + break; + } else if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + if (UNEXPECTED(!Z_ISREF_P(arg))) { + if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + /* By-value send is not allowed -- emit a warning, + * but still perform the call. */ + zend_param_must_be_ref(EX(call)->func, arg_num); + must_wrap = 1; + } + } + } else { + if (Z_ISREF_P(arg) && + !(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { + /* don't separate references for __call */ + arg = Z_REFVAL_P(arg); + } + } + if (EXPECTED(!must_wrap)) { + ZVAL_COPY(param, arg); + } else { + Z_TRY_ADDREF_P(arg); + ZVAL_NEW_REF(param, arg); + } + ZEND_CALL_NUM_ARGS(EX(call))++; + arg_num++; + param++; + } ZEND_HASH_FOREACH_END(); } + FREE_OP(opline->op2_type, opline->op2.var); + } else { + zend_string *name; + bool have_named_params; + zend_vm_stack_extend_call_frame(&EX(call), 0, zend_hash_num_elements(ht)); + arg_num = 1; + param = ZEND_CALL_ARG(EX(call), 1); + have_named_params = 0; + ZEND_HASH_FOREACH_STR_KEY_VAL(ht, name, arg) { + if (name) { + void *cache_slot[2] = {NULL, NULL}; + have_named_params = 1; + param = zend_handle_named_arg(&EX(call), name, &arg_num, cache_slot); + if (!param) { + FREE_OP(opline->op1_type, opline->op1.var); + HANDLE_EXCEPTION(); + } + } else if (have_named_params) { + zend_throw_error(NULL, + "Cannot use positional argument after named argument"); + FREE_OP(opline->op1_type, opline->op1.var); + HANDLE_EXCEPTION(); + } + + bool must_wrap = 0; + if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + if (UNEXPECTED(!Z_ISREF_P(arg))) { + if (!ARG_MAY_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + /* By-value send is not allowed -- emit a warning, + * but still perform the call. */ + zend_param_must_be_ref(EX(call)->func, arg_num); + must_wrap = 1; + } + } + } else { + if (Z_ISREF_P(arg) && + !(EX(call)->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) { + /* don't separate references for __call */ + arg = Z_REFVAL_P(arg); + } + } + + if (EXPECTED(!must_wrap)) { + ZVAL_COPY(param, arg); + } else { + Z_TRY_ADDREF_P(arg); + ZVAL_NEW_REF(param, arg); + } + if (!name) { + ZEND_CALL_NUM_ARGS(EX(call))++; + arg_num++; + param++; + } + } ZEND_HASH_FOREACH_END(); } } - ZEND_VM_NEXT_OPCODE(); + FREE_OP(opline->op1_type, opline->op1.var); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_CLASS_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_missing_arg_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE SAVE_OPLINE(); - do_bind_class(RT_CONSTANT(opline, opline->op1), (opline->op2_type == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + zend_missing_arg_error(execute_data); + HANDLE_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_verify_recv_arg_type_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RECV_NOTYPE_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_function *func; - zval *object; - zend_class_entry *called_scope; + uint32_t arg_num = opline->op1.num; - func = (zend_function *) EX(func)->op_array.dynamic_func_defs[opline->op2.num]; - if (Z_TYPE(EX(This)) == IS_OBJECT) { - called_scope = Z_OBJCE(EX(This)); - if (UNEXPECTED((func->common.fn_flags & ZEND_ACC_STATIC) || - (EX(func)->common.fn_flags & ZEND_ACC_STATIC))) { - object = NULL; - } else { - object = &EX(This); - } - } else { - called_scope = Z_CE(EX(This)); - object = NULL; + if (UNEXPECTED(arg_num > EX_NUM_ARGS())) { + ZEND_VM_TAIL_CALL(zend_missing_arg_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - SAVE_OPLINE(); - zend_create_closure(EX_VAR(opline->result.var), func, - EX(func)->op_array.scope, called_scope, object); ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_FROM_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_case_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX zval *op_1, zval *op_2); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_UNPACK_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - zval *val; + zval *op1; + HashTable *result_ht; SAVE_OPLINE(); - val = RT_CONSTANT(opline, opline->op1); - - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator"); + op1 = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R); + result_ht = Z_ARRVAL_P(EX_VAR(opline->result.var)); +add_unpack_again: + if (EXPECTED(Z_TYPE_P(op1) == IS_ARRAY)) { + HashTable *ht = Z_ARRVAL_P(op1); + zval *val; - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } + if (HT_IS_PACKED(ht) && (zend_hash_num_elements(result_ht) == 0 || HT_IS_PACKED(result_ht))) { + /* zend_hash_extend() skips initialization when the number of elements is 0, + * but the code below expects that result_ht is initialized as packed. + * We can just skip the work in that case. */ + if (result_ht->nNumUsed + zend_hash_num_elements(ht) > 0) { + zend_hash_extend(result_ht, result_ht->nNumUsed + zend_hash_num_elements(ht), 1); + ZEND_HASH_FILL_PACKED(result_ht) { + ZEND_HASH_PACKED_FOREACH_VAL(ht, val) { + if (UNEXPECTED(Z_ISREF_P(val)) && + UNEXPECTED(Z_REFCOUNT_P(val) == 1)) { + val = Z_REFVAL_P(val); + } + Z_TRY_ADDREF_P(val); + ZEND_HASH_FILL_ADD(val); + } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FILL_END(); + } + } else { + zend_string *key; -yield_from_try_again: - if (Z_TYPE_P(val) == IS_ARRAY) { - ZVAL_COPY_VALUE(&generator->values, val); - if (Z_OPT_REFCOUNTED_P(val)) { - Z_ADDREF_P(val); + ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) { + if (UNEXPECTED(Z_ISREF_P(val)) && + UNEXPECTED(Z_REFCOUNT_P(val) == 1)) { + val = Z_REFVAL_P(val); + } + Z_TRY_ADDREF_P(val); + if (key) { + zend_hash_update(result_ht, key, val); + } else { + if (!zend_hash_next_index_insert(result_ht, val)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(val); + break; + } + } + } ZEND_HASH_FOREACH_END(); } - Z_FE_POS(generator->values) = 0; + } else if (EXPECTED(Z_TYPE_P(op1) == IS_OBJECT)) { + zend_class_entry *ce = Z_OBJCE_P(op1); + zend_object_iterator *iter; + if (!ce || !ce->get_iterator) { + zend_type_error("Only arrays and Traversables can be unpacked, %s given", zend_zval_value_name(op1)); + } else { + iter = ce->get_iterator(ce, op1, 0); + if (UNEXPECTED(!iter)) { + FREE_OP(opline->op1_type, opline->op1.var); + if (!EG(exception)) { + zend_throw_exception_ex( + NULL, 0, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name) + ); + } + HANDLE_EXCEPTION(); + } - } else if (IS_CONST != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) { - zend_class_entry *ce = Z_OBJCE_P(val); - if (ce == zend_ce_generator) { - zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); + const zend_object_iterator_funcs *funcs = iter->funcs; + if (funcs->rewind) { + funcs->rewind(iter); + } - Z_ADDREF_P(val); + for (; funcs->valid(iter) == SUCCESS; ) { + zval *val; + if (UNEXPECTED(EG(exception) != NULL)) { + break; + } - if (UNEXPECTED(new_gen->execute_data == NULL)) { - zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); - zval_ptr_dtor(val); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else if (Z_ISUNDEF(new_gen->retval)) { - if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) { - zend_throw_error(NULL, "Impossible to yield from the Generator being currently run"); - zval_ptr_dtor(val); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else { - zend_generator_yield_from(generator, new_gen); + val = funcs->get_current_data(iter); + if (UNEXPECTED(EG(exception) != NULL)) { + break; } - } else { - if (RETURN_VALUE_USED(opline)) { - ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval); + + zval key; + if (funcs->get_current_key) { + funcs->get_current_key(iter, &key); + if (UNEXPECTED(EG(exception) != NULL)) { + break; + } + + if (UNEXPECTED(Z_TYPE(key) != IS_LONG && Z_TYPE(key) != IS_STRING)) { + zend_throw_error(NULL, + "Keys must be of type int|string during array unpacking"); + zval_ptr_dtor(&key); + break; + } + } else { + ZVAL_UNDEF(&key); } - ZEND_VM_NEXT_OPCODE(); - } - } else { - zend_object_iterator *iter = ce->get_iterator(ce, val, 0); + ZVAL_DEREF(val); + Z_TRY_ADDREF_P(val); - if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) { - if (!EG(exception)) { - zend_throw_error(NULL, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name)); + zend_ulong num_key; + if (Z_TYPE(key) == IS_STRING && !ZEND_HANDLE_NUMERIC(Z_STR(key), num_key)) { + zend_hash_update(result_ht, Z_STR(key), val); + zval_ptr_dtor_str(&key); + } else { + zval_ptr_dtor(&key); + if (!zend_hash_next_index_insert(result_ht, val)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(val); + break; + } } - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - iter->index = 0; - if (iter->funcs->rewind) { - iter->funcs->rewind(iter); - if (UNEXPECTED(EG(exception) != NULL)) { - OBJ_RELEASE(&iter->std); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); + funcs->move_forward(iter); + if (UNEXPECTED(EG(exception))) { + break; } } - ZVAL_OBJ(&generator->values, &iter->std); + zend_iterator_dtor(iter); } - } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(val) == IS_REFERENCE) { - val = Z_REFVAL_P(val); - goto yield_from_try_again; + } else if (EXPECTED(Z_ISREF_P(op1))) { + op1 = Z_REFVAL_P(op1); + goto add_unpack_again; } else { - zend_throw_error(NULL, "Can use \"yield from\" only with arrays and Traversables"); + zend_throw_error(NULL, "Only arrays and Traversables can be unpacked, %s given", zend_zval_value_name(op1)); + } + FREE_OP(opline->op1_type, opline->op1.var); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_STATIC_PROP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *varname; + zend_string *name, *tmp_name = NULL; + zend_class_entry *ce; - /* This is the default return value - * when the expression is a Generator, it will be overwritten in zend_generator_resume() */ - if (RETURN_VALUE_USED(opline)) { - ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + + if (opline->op2_type == IS_CONST) { + ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + FREE_OP(opline->op1_type, opline->op1.var); + HANDLE_EXCEPTION(); + } + /*CACHE_PTR(opline->extended_value, ce);*/ + } + } else if (opline->op2_type == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + FREE_OP(opline->op1_type, opline->op1.var); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } - /* This generator has no send target (though the generator we delegate to might have one) */ - generator->send_target = NULL; + varname = get_zval_ptr_undef(opline->op1_type, opline->op1, BP_VAR_R); + if (opline->op1_type == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + } else { + if (opline->op1_type == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = ZVAL_UNDEFINED_OP1(); + } + name = zval_try_get_tmp_string(varname, &tmp_name); + if (UNEXPECTED(!name)) { + FREE_OP(opline->op1_type, opline->op1.var); + HANDLE_EXCEPTION(); + } + } - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); + zend_std_unset_static_property(ce, name); - ZEND_VM_RETURN(); + zend_tmp_string_release(tmp_name); + FREE_OP(opline->op1_type, opline->op1.var); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_STRLEN_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_fe_fetch_object_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *array; zval *value; + uint32_t value_type; + HashTable *fe_ht; + HashPosition pos; + Bucket *p; + zend_object_iterator *iter; - value = RT_CONSTANT(opline, opline->op1); - if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(value); - } - ZEND_VM_NEXT_OPCODE(); - } else { - bool strict; - - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) { - value = Z_REFVAL_P(value); - if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + array = EX_VAR(opline->op1.var); + SAVE_OPLINE(); + ZEND_ASSERT(Z_TYPE_P(array) == IS_OBJECT); + if ((iter = zend_iterator_unwrap(array)) == NULL) { + /* plain object */ - ZEND_VM_NEXT_OPCODE(); + fe_ht = Z_OBJPROP_P(array); + pos = zend_hash_iterator_pos(Z_FE_ITER_P(array), fe_ht); + p = fe_ht->arData + pos; + while (1) { + if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { + /* reached end of iteration */ + goto fe_fetch_r_exit; } - } - - SAVE_OPLINE(); - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - value = ZVAL_UNDEFINED_OP1(); - } - strict = EX_USES_STRICT_TYPES(); - do { - if (EXPECTED(!strict)) { - zend_string *str; - zval tmp; - - if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) { - zend_error(E_DEPRECATED, - "strlen(): Passing null to parameter #1 ($string) of type string is deprecated"); - ZVAL_LONG(EX_VAR(opline->result.var), 0); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + pos++; + value = &p->val; + value_type = Z_TYPE_INFO_P(value); + if (EXPECTED(value_type != IS_UNDEF)) { + if (UNEXPECTED(value_type == IS_INDIRECT)) { + value = Z_INDIRECT_P(value); + value_type = Z_TYPE_INFO_P(value); + if (EXPECTED(value_type != IS_UNDEF) + && EXPECTED(zend_check_property_access(Z_OBJ_P(array), p->key, 0) == SUCCESS)) { + break; } + } else if (EXPECTED(Z_OBJCE_P(array)->default_properties_count == 0) + || !p->key + || zend_check_property_access(Z_OBJ_P(array), p->key, 1) == SUCCESS) { break; } - - ZVAL_COPY(&tmp, value); - if (zend_parse_arg_str_weak(&tmp, &str, 1)) { - ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str)); - zval_ptr_dtor(&tmp); - break; + } + p++; + } + EG(ht_iterators)[Z_FE_ITER_P(array)].pos = pos; + if (RETURN_VALUE_USED(opline)) { + if (UNEXPECTED(!p->key)) { + ZVAL_LONG(EX_VAR(opline->result.var), p->h); + } else if (ZSTR_VAL(p->key)[0]) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); + } else { + const char *class_name, *prop_name; + size_t prop_name_len; + zend_unmangle_property_name_ex( + p->key, &class_name, &prop_name, &prop_name_len); + ZVAL_STRINGL(EX_VAR(opline->result.var), prop_name, prop_name_len); + } + } + } else { + const zend_object_iterator_funcs *funcs = iter->funcs; + if (EXPECTED(++iter->index > 0)) { + /* This could cause an endless loop if index becomes zero again. + * In case that ever happens we need an additional flag. */ + funcs->move_forward(iter); + if (UNEXPECTED(EG(exception) != NULL)) { + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + if (UNEXPECTED(funcs->valid(iter) == FAILURE)) { + /* reached end of iteration */ + if (UNEXPECTED(EG(exception) != NULL)) { + UNDEF_RESULT(); + HANDLE_EXCEPTION(); } - zval_ptr_dtor(&tmp); +fe_fetch_r_exit: + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } - if (!EG(exception)) { - zend_type_error("strlen(): Argument #1 ($string) must be of type string, %s given", zend_zval_value_name(value)); + } + value = funcs->get_current_data(iter); + if (UNEXPECTED(EG(exception) != NULL)) { + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + if (!value) { + /* failure in get_current_data */ + goto fe_fetch_r_exit; + } + if (RETURN_VALUE_USED(opline)) { + if (funcs->get_current_key) { + funcs->get_current_key(iter, EX_VAR(opline->result.var)); + if (UNEXPECTED(EG(exception) != NULL)) { + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + } else { + ZVAL_LONG(EX_VAR(opline->result.var), iter->index); } - ZVAL_UNDEF(EX_VAR(opline->result.var)); - } while (0); + } + value_type = Z_TYPE_INFO_P(value); } + if (EXPECTED(opline->op2_type == IS_CV)) { + zval *variable_ptr = EX_VAR(opline->op2.var); + zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); + } else { + zval *res = EX_VAR(opline->op2.var); + zend_refcounted *gc = Z_COUNTED_P(value); + ZVAL_COPY_VALUE_EX(res, value, gc, value_type); + if (Z_TYPE_INFO_REFCOUNTED(value_type)) { + GC_ADDREF(gc); + } + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_TYPE_CHECK_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_STATIC_PROP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *value; - int result = 0; + bool result; - value = RT_CONSTANT(opline, opline->op1); - if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { -type_check_resource: - if (opline->extended_value != MAY_BE_RESOURCE - || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) { - result = 1; - } - } else if ((IS_CONST & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) { - value = Z_REFVAL_P(value); - if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { - goto type_check_resource; - } - } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - result = ((1 << IS_NULL) & opline->extended_value) != 0; - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - SAVE_OPLINE(); + SAVE_OPLINE(); + value = zend_fetch_static_property_address(NULL, opline->extended_value & ~ZEND_ISEMPTY, BP_VAR_IS, 0 OPLINE_CC EXECUTE_DATA_CC); - ZEND_VM_SMART_BRANCH(result, 1); + if (!(opline->extended_value & ZEND_ISEMPTY)) { + result = value != NULL && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); } else { - ZEND_VM_SMART_BRANCH(result, 0); + result = value == NULL || !i_zend_is_true(value); } + + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DEFINED_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BEGIN_SILENCE_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_constant *c; - c = CACHED_PTR(opline->extended_value); - if (EXPECTED(c != NULL)) { - if (!IS_SPECIAL_CACHE_VAL(c)) { -defined_true: - ZEND_VM_SMART_BRANCH_TRUE(); - } else if (EXPECTED(zend_hash_num_elements(EG(zend_constants)) == DECODE_SPECIAL_CACHE_NUM(c))) { -defined_false: - ZEND_VM_SMART_BRANCH_FALSE(); - } + ZVAL_LONG(EX_VAR(opline->result.var), EG(error_reporting)); + + if (!E_HAS_ONLY_FATAL_ERRORS(EG(error_reporting))) { + do { + /* Do not silence fatal errors */ + EG(error_reporting) &= E_FATAL_ERRORS; + if (!EG(error_reporting_ini_entry)) { + zval *zv = zend_hash_find_known_hash(EG(ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING)); + if (zv) { + EG(error_reporting_ini_entry) = (zend_ini_entry *)Z_PTR_P(zv); + } else { + break; + } + } + if (!EG(error_reporting_ini_entry)->modified) { + if (!EG(modified_ini_directives)) { + ALLOC_HASHTABLE(EG(modified_ini_directives)); + zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0); + } + if (EXPECTED(zend_hash_add_ptr(EG(modified_ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING), EG(error_reporting_ini_entry)) != NULL)) { + EG(error_reporting_ini_entry)->orig_value = EG(error_reporting_ini_entry)->value; + EG(error_reporting_ini_entry)->orig_modifiable = EG(error_reporting_ini_entry)->modifiable; + EG(error_reporting_ini_entry)->modified = 1; + } + } + } while (0); } - if (zend_quick_check_constant(RT_CONSTANT(opline, opline->op1) OPLINE_CC EXECUTE_DATA_CC) != SUCCESS) { - CACHE_PTR(opline->extended_value, ENCODE_SPECIAL_CACHE_NUM(zend_hash_num_elements(EG(zend_constants)))); - goto defined_false; - } else { - goto defined_true; + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_EXT_STMT_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (!EG(no_extensions)) { + SAVE_OPLINE(); + zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_statement_handler, execute_data); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_EXT_FCALL_BEGIN_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (!EG(no_extensions)) { + SAVE_OPLINE(); + zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_begin_handler, execute_data); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_FRAMELESS_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_EXT_FCALL_END_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_jmp_fl_result result = (uintptr_t)CACHED_PTR(opline->extended_value); -try_again: - if (EXPECTED(result == ZEND_JMP_FL_HIT)) { - OPLINE = OP_JMP_ADDR(opline, opline->op2); - ZEND_VM_CONTINUE(); - } else if (EXPECTED(result == ZEND_JMP_FL_MISS)) { - ZEND_VM_NEXT_OPCODE(); - } else { - ZEND_ASSERT(result == ZEND_JMP_FL_UNPRIMED); - /* func_name refers to the function in the local namespace, e.g. foo\substr. */ - zval *func_name = (zval *)RT_CONSTANT(opline, opline->op1); - /* If it cannot be found locally, we must be referring to the global function. */ - zval *func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(func_name)); - /* ZEND_JMP_FL_MISS = 1, ZEND_JMP_FL_HIT = 2 */ - result = (func == NULL) + 1; - CACHE_PTR(opline->extended_value, (void *)result); - goto try_again; + + if (!EG(no_extensions)) { + SAVE_OPLINE(); + zend_llist_apply_with_argument(&zend_extensions, (llist_apply_with_arg_func_t) zend_extension_fcall_end_handler, execute_data); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_LONG_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_ANON_CLASS_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zval *zv; + zend_class_entry *ce; USE_OPLINE - zval *value; - value = RT_CONSTANT(opline, opline->op1); - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(value)); + ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + zend_string *rtd_key = Z_STR_P(RT_CONSTANT(opline, opline->op1)); + zv = zend_hash_find_known_hash(EG(class_table), rtd_key); + ZEND_ASSERT(zv != NULL); + ce = Z_CE_P(zv); + if (!(ce->ce_flags & ZEND_ACC_LINKED)) { + SAVE_OPLINE(); + ce = zend_do_link_class(ce, (opline->op2_type == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL, rtd_key); + if (EG(exception)) { + HANDLE_EXCEPTION(); + } + } + CACHE_PTR(opline->extended_value, ce); + } + Z_CE_P(EX_VAR(opline->result.var)) = ce; ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_FUNCTION_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zend_function *func; USE_OPLINE - zval *value; - value = RT_CONSTANT(opline, opline->op1); - ZVAL_DOUBLE(EX_VAR(opline->result.var), Z_DVAL_P(value)); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + func = (zend_function *) EX(func)->op_array.dynamic_func_defs[opline->op2.num]; + do_bind_function(func, RT_CONSTANT(opline, opline->op1)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_NOREF_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_TICKS_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - value = RT_CONSTANT(opline, opline->op1); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + if (++EG(ticks_count) >= opline->extended_value) { + EG(ticks_count) = 0; + if (zend_ticks_function) { + SAVE_OPLINE(); + zend_fiber_switch_block(); + zend_ticks_function(opline->extended_value); + zend_fiber_switch_unblock(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_SIMPLE_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_EXT_NOP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value, *arg; - value = RT_CONSTANT(opline, opline->op1); - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - ZVAL_COPY_VALUE(arg, value); ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NOP_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value, *arg; - uint32_t arg_num = opline->op2.num; - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg)); - } - value = RT_CONSTANT(opline, opline->op1); - ZVAL_COPY_VALUE(arg, value); ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_dispatch_try_catch_finally_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t try_catch_offset, uint32_t op_num); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_HANDLE_EXCEPTION_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zval *op1, *op2, *result; - double d1, d2; + const zend_op *throw_op = EG(opline_before_exception); - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - fast_long_add_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto add_double; + /* Exception was thrown before executing any op */ + if (UNEXPECTED(!throw_op)) { + ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX -1, 0)); + } + + uint32_t throw_op_num = throw_op - EX(func)->op_array.opcodes; + uint32_t current_try_catch_offset = -1; + + if ((throw_op->opcode == ZEND_FREE || throw_op->opcode == ZEND_FE_FREE) + && throw_op->extended_value & ZEND_FREE_ON_RETURN) { + /* exceptions thrown because of loop var destruction on return/break/... + * are logically thrown at the end of the foreach loop, so adjust the + * throw_op_num. + */ + const zend_live_range *range = find_live_range( + &EX(func)->op_array, throw_op_num, throw_op->op1.var); + /* free op1 of the corresponding RETURN */ + for (uint32_t i = throw_op_num; i < range->end; i++) { + if (EX(func)->op_array.opcodes[i].opcode == ZEND_FREE + || EX(func)->op_array.opcodes[i].opcode == ZEND_FE_FREE) { + /* pass */ + } else { + if (EX(func)->op_array.opcodes[i].opcode == ZEND_RETURN + && (EX(func)->op_array.opcodes[i].op1_type & (IS_VAR|IS_TMP_VAR))) { + zval_ptr_dtor(EX_VAR(EX(func)->op_array.opcodes[i].op1.var)); + } + break; + } } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -add_double: - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, d1 + d2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto add_double; + throw_op_num = range->end; + } + + /* Find the innermost try/catch/finally the exception was thrown in */ + for (uint32_t i = 0; i < EX(func)->op_array.last_try_catch; i++) { + zend_try_catch_element *try_catch = &EX(func)->op_array.try_catch_array[i]; + if (try_catch->try_op > throw_op_num) { + /* further blocks will not be relevant... */ + break; + } + if (throw_op_num < try_catch->catch_op || throw_op_num < try_catch->finally_end) { + current_try_catch_offset = i; } } - ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} + cleanup_unfinished_calls(execute_data, throw_op_num); -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - double d1, d2; + if (throw_op->result_type & (IS_VAR | IS_TMP_VAR)) { + switch (throw_op->opcode) { + case ZEND_ADD_ARRAY_ELEMENT: + case ZEND_ADD_ARRAY_UNPACK: + case ZEND_ROPE_INIT: + case ZEND_ROPE_ADD: + break; /* exception while building structures, live range handling will free those */ - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - fast_long_sub_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto sub_double; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -sub_double: - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, d1 - d2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto sub_double; + case ZEND_FETCH_CLASS: + case ZEND_DECLARE_ANON_CLASS: + break; /* return value is zend_class_entry pointer */ + + default: + /* smart branch opcodes may not initialize result */ + if (!zend_is_smart_branch(throw_op)) { + zval_ptr_dtor_nogc(EX_VAR(throw_op->result.var)); + } } } - ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX current_try_catch_offset, throw_op_num)); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_USER_OPCODE_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; - double d1, d2; + int ret; - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - zend_long overflow; + SAVE_OPLINE(); + ret = zend_user_opcode_handlers[opline->opcode](execute_data); + opline = EX(opline); - result = EX_VAR(opline->result.var); - ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); - Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto mul_double; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -mul_double: - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, d1 * d2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto mul_double; - } + switch (ret) { + case ZEND_USER_OPCODE_CONTINUE: + ZEND_VM_CONTINUE(); + case ZEND_USER_OPCODE_RETURN: + if (UNEXPECTED((EX_CALL_INFO() & ZEND_CALL_GENERATOR) != 0)) { + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + EG(current_execute_data) = EX(prev_execute_data); + zend_generator_close(generator, 1); + ZEND_VM_RETURN(); + } else { + ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); + } + case ZEND_USER_OPCODE_ENTER: + ZEND_VM_ENTER(); + case ZEND_USER_OPCODE_LEAVE: + ZEND_VM_LEAVE(); + case ZEND_USER_OPCODE_DISPATCH: + ZEND_VM_DISPATCH(opline->opcode, opline); + default: + ZEND_VM_DISPATCH((uint8_t)(ret & 0xff), opline); } - - ZEND_VM_DISPATCH_TO_HELPER(zend_mul_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; SAVE_OPLINE(); - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - div_function(EX_VAR(opline->result.var), op1, op2); + zend_throw_error(NULL, "Cannot yield from finally in a force-closed generator"); + FREE_OP(opline->op2_type, opline->op2.var); + FREE_OP(opline->op1_type, opline->op1.var); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DISCARD_EXCEPTION_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *fast_call = EX_VAR(opline->op1.var); + SAVE_OPLINE(); + /* cleanup incomplete RETURN statement */ + if (Z_OPLINE_NUM_P(fast_call) != (uint32_t)-1 + && (EX(func)->op_array.opcodes[Z_OPLINE_NUM_P(fast_call)].op2_type & (IS_TMP_VAR | IS_VAR))) { + zval *return_value = EX_VAR(EX(func)->op_array.opcodes[Z_OPLINE_NUM_P(fast_call)].op2.var); + zval_ptr_dtor(return_value); + } + /* cleanup delayed exception */ + if (Z_OBJ_P(fast_call) != NULL) { + /* discard the previously thrown exception */ + OBJ_RELEASE(Z_OBJ_P(fast_call)); + Z_OBJ_P(fast_call) = NULL; + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MOD_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CALL_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; - - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { - ZEND_VM_TAIL_CALL(zend_mod_by_zero_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) { - /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */ - ZVAL_LONG(result, 0); - } else { - ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2)); - } - ZEND_VM_NEXT_OPCODE(); - } - } + zval *fast_call = EX_VAR(opline->result.var); - ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + Z_OBJ_P(fast_call) = NULL; + /* set return address */ + Z_OPLINE_NUM_P(fast_call) = opline - EX(func)->op_array.opcodes; + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op1), 0); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_RET_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *fast_call = EX_VAR(opline->op1.var); + uint32_t current_try_catch_offset, current_op_num; - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) - && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { - /* Perform shift on unsigned numbers to get well-defined wrap behavior. */ - ZVAL_LONG(EX_VAR(opline->result.var), - (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2))); - ZEND_VM_NEXT_OPCODE(); + if (Z_OPLINE_NUM_P(fast_call) != (uint32_t)-1) { + const zend_op *fast_ret = EX(func)->op_array.opcodes + Z_OPLINE_NUM_P(fast_call); + + ZEND_VM_JMP_EX(fast_ret + 1, 0); } - ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + /* special case for unhandled exceptions */ + EG(exception) = Z_OBJ_P(fast_call); + Z_OBJ_P(fast_call) = NULL; + current_try_catch_offset = opline->op2.num; + current_op_num = opline - EX(func)->op_array.opcodes; + ZEND_VM_DISPATCH_TO_HELPER(zend_dispatch_try_catch_finally_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX current_try_catch_offset, current_op_num)); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SR_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSERT_CHECK_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) - && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2)); + if (EG(assertions) <= 0) { + zend_op *target = OP_JMP_ADDR(opline, opline->op2); + if (RETURN_VALUE_USED(opline)) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + } + ZEND_VM_JMP_EX(target, 0); + } else { ZEND_VM_NEXT_OPCODE(); } - - ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CALL_TRAMPOLINE_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zval *op1, *op2; + zend_array *args = NULL; + zend_function *fbc = EX(func); + zval *ret = EX(return_value); + uint32_t call_info = EX_CALL_INFO() & (ZEND_CALL_NESTED | ZEND_CALL_TOP | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_EXTRA_NAMED_PARAMS); + uint32_t num_args = EX_NUM_ARGS(); + zend_execute_data *call; + + SAVE_OPLINE(); + + if (num_args) { + zval *p = ZEND_CALL_ARG(execute_data, 1); + zval *end = p + num_args; + + args = zend_new_array(num_args); + zend_hash_real_init_packed(args); + ZEND_HASH_FILL_PACKED(args) { + do { + ZEND_HASH_FILL_ADD(p); + p++; + } while (p != end); + } ZEND_HASH_FILL_END(); + } + + call = execute_data; + execute_data = EG(current_execute_data) = EX(prev_execute_data); + + call->func = (fbc->op_array.fn_flags & ZEND_ACC_STATIC) ? fbc->op_array.scope->__callstatic : fbc->op_array.scope->__call; + ZEND_ASSERT(zend_vm_calc_used_stack(2, call->func) <= (size_t)(((char*)EG(vm_stack_end)) - (char*)call)); + ZEND_CALL_NUM_ARGS(call) = 2; + + ZVAL_STR(ZEND_CALL_ARG(call, 1), fbc->common.function_name); + + zval *call_args = ZEND_CALL_ARG(call, 2); + if (args) { + ZVAL_ARR(call_args, args); + } else { + ZVAL_EMPTY_ARRAY(call_args); + } + if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { + if (zend_hash_num_elements(Z_ARRVAL_P(call_args)) == 0) { + GC_ADDREF(call->extra_named_params); + ZVAL_ARR(call_args, call->extra_named_params); + } else { + SEPARATE_ARRAY(call_args); + zend_hash_copy(Z_ARRVAL_P(call_args), call->extra_named_params, zval_add_ref); + } + } + zend_free_trampoline(fbc); + fbc = call->func; + + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { + if (UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + if (EXPECTED(zend_execute_ex == execute_ex)) { + LOAD_OPLINE_EX(); + + + + + ZEND_VM_ENTER_EX(); + } else { + SAVE_OPLINE_EX(); + + + execute_data = EX(prev_execute_data); + if (execute_data) { + LOAD_OPLINE(); + } + ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); + zend_execute_ex(call); + } + } else { + zval retval; + + ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); + + EG(current_execute_data) = call; + +#if ZEND_DEBUG + bool should_throw = zend_internal_call_should_throw(fbc, call); +#endif + + if (ret == NULL) { + ret = &retval; + } + + ZVAL_NULL(ret); + + + if (!zend_execute_internal) { + /* saves one function call if zend_execute_internal is not used */ + fbc->internal_function.handler(call, ret); + } else { + zend_execute_internal(call, ret); + } + +#if ZEND_DEBUG + if (!EG(exception) && call->func) { + if (should_throw) { + zend_internal_call_arginfo_violation(call->func); + } + ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, ret)); + ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) + ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); + zend_verify_internal_func_info(call->func, ret); + } +#endif + + + EG(current_execute_data) = call->prev_execute_data; + + zend_vm_stack_free_args(call); + if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { + zend_free_extra_named_params(call->extra_named_params); + } + if (ret == &retval) { + zval_ptr_dtor(ret); + } + } - SAVE_OPLINE(); - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - pow_function(EX_VAR(opline->result.var), op1, op2); + execute_data = EG(current_execute_data); + if (!execute_data || !EX(func) || !ZEND_USER_CODE(EX(func)->type) || (call_info & ZEND_CALL_TOP)) { + ZEND_VM_RETURN(); + } + if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { + zend_object *object = Z_OBJ(call->This); + OBJ_RELEASE(object); + } + zend_vm_stack_free_call_frame(call); + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION_LEAVE(); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + LOAD_OPLINE(); + ZEND_VM_INC_OPCODE(); + ZEND_VM_LEAVE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zval *op1, *op2; - bool result; + zend_array *args = NULL; + zend_function *fbc = EX(func); + zval *ret = EX(return_value); + uint32_t call_info = EX_CALL_INFO() & (ZEND_CALL_NESTED | ZEND_CALL_TOP | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_EXTRA_NAMED_PARAMS); + uint32_t num_args = EX_NUM_ARGS(); + zend_execute_data *call; SAVE_OPLINE(); - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_identical_function(op1, op2); - + if (num_args) { + zval *p = ZEND_CALL_ARG(execute_data, 1); + zval *end = p + num_args; + args = zend_new_array(num_args); + zend_hash_real_init_packed(args); + ZEND_HASH_FILL_PACKED(args) { + do { + ZEND_HASH_FILL_ADD(p); + p++; + } while (p != end); + } ZEND_HASH_FILL_END(); + } - ZEND_VM_SMART_BRANCH(result, 1); -} + call = execute_data; + execute_data = EG(current_execute_data) = EX(prev_execute_data); -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + call->func = (fbc->op_array.fn_flags & ZEND_ACC_STATIC) ? fbc->op_array.scope->__callstatic : fbc->op_array.scope->__call; + ZEND_ASSERT(zend_vm_calc_used_stack(2, call->func) <= (size_t)(((char*)EG(vm_stack_end)) - (char*)call)); + ZEND_CALL_NUM_ARGS(call) = 2; - SAVE_OPLINE(); - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_not_identical_function(op1, op2); + ZVAL_STR(ZEND_CALL_ARG(call, 1), fbc->common.function_name); + zval *call_args = ZEND_CALL_ARG(call, 2); + if (args) { + ZVAL_ARR(call_args, args); + } else { + ZVAL_EMPTY_ARRAY(call_args); + } + if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { + if (zend_hash_num_elements(Z_ARRVAL_P(call_args)) == 0) { + GC_ADDREF(call->extra_named_params); + ZVAL_ARR(call_args, call->extra_named_params); + } else { + SEPARATE_ARRAY(call_args); + zend_hash_copy(Z_ARRVAL_P(call_args), call->extra_named_params, zval_add_ref); + } + } + zend_free_trampoline(fbc); + fbc = call->func; + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { + if (UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + execute_data = call; + i_init_func_execute_data(&fbc->op_array, ret, 0 EXECUTE_DATA_CC); + if (EXPECTED(zend_execute_ex == execute_ex)) { + LOAD_OPLINE_EX(); + SAVE_OPLINE(); + zend_observer_fcall_begin_specialized(execute_data, false); + ZEND_VM_ENTER_EX(); + } else { + SAVE_OPLINE_EX(); + zend_observer_fcall_begin_specialized(execute_data, false); + execute_data = EX(prev_execute_data); + if (execute_data) { + LOAD_OPLINE(); + } + ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); + zend_execute_ex(call); + } + } else { + zval retval; + ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); - ZEND_VM_SMART_BRANCH(result, 1); -} + EG(current_execute_data) = call; -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; +#if ZEND_DEBUG + bool should_throw = zend_internal_call_should_throw(fbc, call); +#endif - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; + if (ret == NULL) { + ret = &retval; } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; + + ZVAL_NULL(ret); + zend_observer_fcall_begin_specialized(call, false); + if (!zend_execute_internal) { + /* saves one function call if zend_execute_internal is not used */ + fbc->internal_function.handler(call, ret); + } else { + zend_execute_internal(call, ret); } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; + +#if ZEND_DEBUG + if (!EG(exception) && call->func) { + if (should_throw) { + zend_internal_call_arginfo_violation(call->func); } + ZEND_ASSERT(!(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, ret)); + ZEND_ASSERT((call->func->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) + ? Z_ISREF_P(ret) : !Z_ISREF_P(ret)); + zend_verify_internal_func_info(call->func, ret); } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} +#endif + zend_observer_fcall_end(call, EG(exception) ? NULL : ret); -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; + EG(current_execute_data) = call->prev_execute_data; - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; + zend_vm_stack_free_args(call); + if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { + zend_free_extra_named_params(call->extra_named_params); } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } + if (ret == &retval) { + zval_ptr_dtor(ret); } } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; + execute_data = EG(current_execute_data); - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { -is_smaller_true: - ZEND_VM_SMART_BRANCH_TRUE(); - } else { -is_smaller_false: - ZEND_VM_SMART_BRANCH_FALSE(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_smaller_double; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_smaller_double: - if (d1 < d2) { - goto is_smaller_true; - } else { - goto is_smaller_false; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_smaller_double; - } + if (!execute_data || !EX(func) || !ZEND_USER_CODE(EX(func)->type) || (call_info & ZEND_CALL_TOP)) { + ZEND_VM_RETURN(); } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; + if (UNEXPECTED(call_info & ZEND_CALL_RELEASE_THIS)) { + zend_object *object = Z_OBJ(call->This); + OBJ_RELEASE(object); + } + zend_vm_stack_free_call_frame(call); - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { -is_smaller_or_equal_true: - ZEND_VM_SMART_BRANCH_TRUE(); - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } else { -is_smaller_or_equal_false: - ZEND_VM_SMART_BRANCH_FALSE(); - ZVAL_FALSE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_smaller_or_equal_double; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_smaller_or_equal_double: - if (d1 <= d2) { - goto is_smaller_or_equal_true; - } else { - goto is_smaller_or_equal_false; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_smaller_or_equal_double; - } + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION_LEAVE(); } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + + LOAD_OPLINE(); + ZEND_VM_INC_OPCODE(); + ZEND_VM_LEAVE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_2_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - SAVE_OPLINE(); - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - compare_function(EX_VAR(opline->result.var), op1, op2); - + zval *result = EX_VAR(opline->result.var); + ZVAL_NULL(result); + zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R); + zval *arg2 = get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R); + if (EG(exception)) { + FREE_OP(opline->op1_type, opline->op1.var); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } +#if 0 || 0 + if (0 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) { + zend_frameless_observed_call(execute_data); + } else +#endif + { + zend_frameless_function_2 function = (zend_frameless_function_2)ZEND_FLF_HANDLER(opline); + function(result, arg1, arg2); + } + FREE_OP(opline->op1_type, opline->op1.var); + /* Set OP1 to UNDEF in case FREE_OP(opline->op2_type, opline->op2.var) throws. */ + if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->op1.var)); + } + FREE_OP(opline->op2_type, opline->op2.var); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_OR_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_2_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + SAVE_OPLINE(); - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); + zval *result = EX_VAR(opline->result.var); + ZVAL_NULL(result); + zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R); + zval *arg2 = get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R); + if (EG(exception)) { + FREE_OP(opline->op1_type, opline->op1.var); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); } - ZEND_VM_DISPATCH_TO_HELPER(zend_bw_or_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_AND_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); +#if 0 || 1 + if (1 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) { + zend_frameless_observed_call(execute_data); + } else +#endif + { + zend_frameless_function_2 function = (zend_frameless_function_2)ZEND_FLF_HANDLER(opline); + function(result, arg1, arg2); } - ZEND_VM_DISPATCH_TO_HELPER(zend_bw_and_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_XOR_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); + FREE_OP(opline->op1_type, opline->op1.var); + /* Set OP1 to UNDEF in case FREE_OP(opline->op2_type, opline->op2.var) throws. */ + if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->op1.var)); } - - ZEND_VM_DISPATCH_TO_HELPER(zend_bw_xor_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + FREE_OP(opline->op2_type, opline->op2.var); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_XOR_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_3_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - SAVE_OPLINE(); - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - boolean_xor_function(EX_VAR(opline->result.var), op1, op2); - + zval *result = EX_VAR(opline->result.var); + ZVAL_NULL(result); + zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R); + zval *arg2 = get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R); + zval *arg3 = get_op_data_zval_ptr_deref_r((opline+1)->op1_type, (opline+1)->op1); + if (EG(exception)) { + FREE_OP(opline->op1_type, opline->op1.var); + FREE_OP(opline->op2_type, opline->op2.var); + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + HANDLE_EXCEPTION(); + } +#if 0 || 0 + if (0 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) { + zend_frameless_observed_call(execute_data); + } else +#endif + { + zend_frameless_function_3 function = (zend_frameless_function_3)ZEND_FLF_HANDLER(opline); + function(result, arg1, arg2, arg3); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container, *dim, *value; - - SAVE_OPLINE(); - container = RT_CONSTANT(opline, opline->op1); - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST != IS_CONST) { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R EXECUTE_DATA_CC); - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_array; - } else { - goto fetch_dim_r_slow; - } - } else { -fetch_dim_r_slow: - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); - } - } else { - zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); + FREE_OP(opline->op1_type, opline->op1.var); + /* Set to UNDEF in case FREE_OP(opline->op2_type, opline->op2.var) throws. */ + if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->op1.var)); + } + FREE_OP(opline->op2_type, opline->op2.var); + if (opline->op2_type & (IS_VAR|IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->op2.var)); } + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + SAVE_OPLINE(); + zval *result = EX_VAR(opline->result.var); + ZVAL_NULL(result); + zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R); + zval *arg2 = get_zval_ptr_deref(opline->op2_type, opline->op2, BP_VAR_R); + zval *arg3 = get_op_data_zval_ptr_deref_r((opline+1)->op1_type, (opline+1)->op1); + if (EG(exception)) { + FREE_OP(opline->op1_type, opline->op1.var); + FREE_OP(opline->op2_type, opline->op2.var); + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + HANDLE_EXCEPTION(); + } +#if 0 || 1 + if (1 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) { + zend_frameless_observed_call(execute_data); + } else +#endif + { + zend_frameless_function_3 function = (zend_frameless_function_3)ZEND_FLF_HANDLER(opline); + function(result, arg1, arg2, arg3); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + FREE_OP(opline->op1_type, opline->op1.var); + /* Set to UNDEF in case FREE_OP(opline->op2_type, opline->op2.var) throws. */ + if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->op1.var)); + } + FREE_OP(opline->op2_type, opline->op2.var); + if (opline->op2_type & (IS_VAR|IS_TMP_VAR)) { + ZVAL_UNDEF(EX_VAR(opline->op2.var)); + } + FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); + ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_FORWARD_SPEC_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - - SAVE_OPLINE(); - container = RT_CONSTANT(opline, opline->op1); - zend_fetch_dimension_address_read_IS(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); + OPLINE = OP_JMP_ADDR(opline, opline->op1); + ZEND_VM_CONTINUE(); +} +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV zend_interrupt_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS) +{ + zend_atomic_bool_store_ex(&EG(vm_interrupt), false); + SAVE_OPLINE(); + if (zend_atomic_bool_load_ex(&EG(timed_out))) { + zend_timeout(); + } else if (zend_interrupt_function) { + zend_interrupt_function(execute_data); + if (EG(exception)) { + /* We have to UNDEF result, because ZEND_HANDLE_EXCEPTION is going to free it */ + const zend_op *throw_op = EG(opline_before_exception); + if (throw_op + && throw_op->result_type & (IS_TMP_VAR|IS_VAR) + && throw_op->opcode != ZEND_ADD_ARRAY_ELEMENT + && throw_op->opcode != ZEND_ADD_ARRAY_UNPACK + && throw_op->opcode != ZEND_ROPE_INIT + && throw_op->opcode != ZEND_ROPE_ADD) { + ZVAL_UNDEF(ZEND_CALL_VAR(EG(current_execute_data), throw_op->result.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } + ZEND_VM_ENTER(); + } + ZEND_VM_CONTINUE(); } - -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if 0 USE_OPLINE -#endif + zend_function *fbc; + zval *function_name, *func; + zend_execute_data *call; - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + fbc = CACHED_PTR(opline->result.num); + if (UNEXPECTED(fbc == NULL)) { + function_name = (zval*)RT_CONSTANT(opline, opline->op2); + func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(function_name+1)); + if (UNEXPECTED(func == NULL)) { + ZEND_VM_TAIL_CALL(zend_undefined_function_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - if (IS_CONST == IS_UNUSED) { - ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + fbc = Z_FUNC_P(func); + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + CACHE_PTR(opline->result.num, fbc); } + call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + fbc, opline->extended_value, NULL); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - void **cache_slot = NULL; + zval *function_name; + zend_execute_data *call; SAVE_OPLINE(); - container = RT_CONSTANT(opline, opline->op1); + function_name = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CONST || - (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - break; - } - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); +try_function_name: + if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + call = zend_init_dynamic_call_string(Z_STR_P(function_name), opline->extended_value); + } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT)) { + call = zend_init_dynamic_call_object(Z_OBJ_P(function_name), opline->extended_value); + } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY)) { + call = zend_init_dynamic_call_array(Z_ARRVAL_P(function_name), opline->extended_value); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(function_name) == IS_REFERENCE)) { + function_name = Z_REFVAL_P(function_name); + goto try_function_name; + } else { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + function_name = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); } - zend_wrong_property_read(container, RT_CONSTANT(opline, opline->op2)); - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_r_finish; - } while (0); + } + zend_throw_error(NULL, "Value of type %s is not callable", + zend_zval_type_name(function_name)); + call = NULL; } - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; - - if (IS_CONST == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); - - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_r_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { -fetch_obj_r_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - prop_offset = prop_info->offset; - goto fetch_obj_r_simple; - } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { - zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; - ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); - ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); - - uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (IS_CONST & IS_CV) { - GC_ADDREF(zobj); - } - if (IS_CONST & (IS_CV|IS_VAR|IS_TMP_VAR)) { - call_info |= ZEND_CALL_RELEASE_THIS; - } - zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); - call->prev_execute_data = execute_data; - call->call = NULL; - call->return_value = EX_VAR(opline->result.var); - call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); - - execute_data = call; - EG(current_execute_data) = execute_data; - zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); - -#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) - opline = hook->op_array.opcodes; -#else - EX(opline) = hook->op_array.opcodes; -#endif - LOAD_OPLINE_EX(); + if (IS_CONST & (IS_VAR|IS_TMP_VAR)) { + if (UNEXPECTED(EG(exception))) { + if (call) { + if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { + zend_string_release_ex(call->func->common.function_name, 0); + zend_free_trampoline(call->func); + } + zend_vm_stack_free_call_frame(call); + } + HANDLE_EXCEPTION(); + } + } else if (!call) { + HANDLE_EXCEPTION(); + } + call->prev_execute_data = EX(call); + EX(call) = call; - ZEND_VM_ENTER_EX(); - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *func_name; + zval *func; + zend_function *fbc; + zend_execute_data *call; - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; - } - } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; - } - } - } - } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; + fbc = CACHED_PTR(opline->result.num); + if (UNEXPECTED(fbc == NULL)) { + func_name = (zval *)RT_CONSTANT(opline, opline->op2); + func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(func_name + 1)); + if (func == NULL) { + func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(func_name + 2)); + if (UNEXPECTED(func == NULL)) { + ZEND_VM_TAIL_CALL(zend_undefined_function_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } - -#if ZEND_DEBUG - /* For non-standard object handlers, verify a declared property type in debug builds. - * Fetch prop_info before calling read_property(), as it may deallocate the object. */ - zend_property_info *prop_info = NULL; - if (zobj->handlers->read_property != zend_std_read_property) { - prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); - } -#endif - retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); -#if ZEND_DEBUG - if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { - ZVAL_OPT_DEREF(retval); - zend_verify_property_type(prop_info, retval, /* strict */ true); - } -#endif - - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); + fbc = Z_FUNC_P(func); + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); } + CACHE_PTR(opline->result.num, fbc); + } - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_r_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } - } while (0); + call = _zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + fbc, opline->extended_value, NULL); + call->prev_execute_data = EX(call); + EX(call) = call; -fetch_obj_r_finish: + ZEND_VM_NEXT_OPCODE(); +} +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_FCALL_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *fname; + zval *func; + zend_function *fbc; + zend_execute_data *call; + fbc = CACHED_PTR(opline->result.num); + if (UNEXPECTED(fbc == NULL)) { + fname = (zval*)RT_CONSTANT(opline, opline->op2); + func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(fname)); + ZEND_ASSERT(func != NULL && "Function existence must be checked at compile time"); + fbc = Z_FUNC_P(func); + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + CACHE_PTR(opline->result.num, fbc); + } + call = _zend_vm_stack_push_call_frame_ex( + opline->op1.num, ZEND_CALL_NESTED_FUNCTION, + fbc, opline->extended_value, NULL); + call->prev_execute_data = EX(call); + EX(call) = call; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_FCALL_OFFSET_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - void **cache_slot = NULL; - - SAVE_OPLINE(); - container = RT_CONSTANT(opline, opline->op1); - - if (IS_CONST == IS_CONST || - (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - break; - } - } - if (IS_CONST == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - } - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_is_finish; - } while (0); + zend_function *fbc; + zend_execute_data *call; + fbc = CACHED_PTR(opline->result.num); + if (UNEXPECTED(fbc == NULL)) { + fbc = Z_PTR(EG(function_table)->arData[Z_EXTRA_P(RT_CONSTANT(opline, opline->op2))].val); + CACHE_PTR(opline->result.num, fbc); } + call = _zend_vm_stack_push_call_frame_ex( + opline->op1.num, ZEND_CALL_NESTED_FUNCTION, + fbc, opline->extended_value, NULL); + call->prev_execute_data = EX(call); + EX(call) = call; + ZEND_VM_NEXT_OPCODE(); +} - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; - - if (IS_CONST == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RECV_INIT_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + uint32_t arg_num; + zval *param; - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + ZEND_VM_REPEATABLE_OPCODE - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_is_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { -fetch_obj_is_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - goto fetch_obj_is_simple; - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + arg_num = opline->op1.num; + param = EX_VAR(opline->result.var); + if (arg_num > EX_NUM_ARGS()) { + zval *default_value = RT_CONSTANT(opline, opline->op2); - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + if (Z_OPT_TYPE_P(default_value) == IS_CONSTANT_AST) { + zval *cache_val = (zval*)CACHE_ADDR(Z_CACHE_SLOT_P(default_value)); - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } + /* we keep in cache only not refcounted values */ + if (Z_TYPE_P(cache_val) != IS_UNDEF) { + ZVAL_COPY_VALUE(param, cache_val); + } else { + SAVE_OPLINE(); + ZVAL_COPY(param, default_value); + zend_ast_evaluate_ctx ctx = {0}; + if (UNEXPECTED(zval_update_constant_with_ctx(param, EX(func)->op_array.scope, &ctx) != SUCCESS)) { + zval_ptr_dtor_nogc(param); + ZVAL_UNDEF(param); + HANDLE_EXCEPTION(); + } + if (!Z_REFCOUNTED_P(param) && !ctx.had_side_effects) { + ZVAL_COPY_VALUE(cache_val, param); } } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + goto recv_init_check_type; } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; + ZVAL_COPY(param, default_value); + } + } else { +recv_init_check_type: + if ((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0) { + SAVE_OPLINE(); + if (UNEXPECTED(!zend_verify_recv_arg_type(EX(func), arg_num, param))) { + HANDLE_EXCEPTION(); } } + } - retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + ZEND_VM_REPEAT_OPCODE(ZEND_RECV_INIT); + ZEND_VM_NEXT_OPCODE(); +} - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_is_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } - } while (0); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_DYNAMIC_CALL_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + zend_execute_data *call; -fetch_obj_is_finish: + SAVE_OPLINE(); + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); +try_function_name: + if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + call = zend_init_dynamic_call_string(Z_STR_P(function_name), opline->extended_value); + } else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT)) { + call = zend_init_dynamic_call_object(Z_OBJ_P(function_name), opline->extended_value); + } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY)) { + call = zend_init_dynamic_call_array(Z_ARRVAL_P(function_name), opline->extended_value); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(function_name) == IS_REFERENCE)) { + function_name = Z_REFVAL_P(function_name); + goto try_function_name; + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + function_name = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Value of type %s is not callable", + zend_zval_type_name(function_name)); + call = NULL; + } + if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (UNEXPECTED(EG(exception))) { + if (call) { + if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { + zend_string_release_ex(call->func->common.function_name, 0); + zend_free_trampoline(call->func); + } + zend_vm_stack_free_call_frame(call); + } + HANDLE_EXCEPTION(); + } + } else if (!call) { + HANDLE_EXCEPTION(); + } + call->prev_execute_data = EX(call); + EX(call) = call; ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RECV_SPEC_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if 0 USE_OPLINE -#endif + uint32_t arg_num = opline->op1.num; + zval *param; - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - /* Behave like FETCH_OBJ_W */ - if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (UNEXPECTED(arg_num > EX_NUM_ARGS())) { + ZEND_VM_TAIL_CALL(zend_missing_arg_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - SAVE_OPLINE(); - container = RT_CONSTANT(opline, opline->op1); - zend_fetch_dimension_address_LIST_r(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); + param = EX_VAR(opline->result.var); + if (UNEXPECTED(!(opline->op2.num & (1u << Z_TYPE_P(param))))) { + ZEND_VM_DISPATCH_TO_HELPER(zend_verify_recv_arg_type_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX param)); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RECV_VARIADIC_SPEC_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - zend_string *op1_str, *op2_str, *str; + uint32_t arg_num = opline->op1.num; + uint32_t arg_count = EX_NUM_ARGS(); + zval *params; + SAVE_OPLINE(); - op1 = RT_CONSTANT(opline, opline->op1); - op2 = RT_CONSTANT(opline, opline->op2); - if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + params = EX_VAR(opline->result.var); - if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + if (arg_num <= arg_count) { + ZEND_ASSERT(EX(func)->common.fn_flags & ZEND_ACC_VARIADIC); + ZEND_ASSERT(EX(func)->common.num_args == arg_num - 1); + zend_arg_info *arg_info = &EX(func)->common.arg_info[arg_num - 1]; + + array_init_size(params, arg_count - arg_num + 1); + zend_hash_real_init_packed(Z_ARRVAL_P(params)); + ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(params)) { + zval *param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T); + if (ZEND_TYPE_IS_SET(arg_info->type)) { + ZEND_ADD_CALL_FLAG(execute_data, ZEND_CALL_FREE_EXTRA_ARGS); + do { + if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param))) { + ZEND_HASH_FILL_FINISH(); + HANDLE_EXCEPTION(); + } + + if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param); + ZEND_HASH_FILL_ADD(param); + param++; + } while (++arg_num <= arg_count); } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); + do { + if (Z_OPT_REFCOUNTED_P(param)) Z_ADDREF_P(param); + ZEND_HASH_FILL_ADD(param); + param++; + } while (++arg_num <= arg_count); } - } else if (IS_CONST != IS_CONST && IS_CONST != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); + } ZEND_HASH_FILL_END(); + } else { + ZVAL_EMPTY_ARRAY(params); + } - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } + if (EX_CALL_INFO() & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { + zend_string *name; + zval *param; + zend_arg_info *arg_info = &EX(func)->common.arg_info[EX(func)->common.num_args]; + if (ZEND_TYPE_IS_SET(arg_info->type)) { + SEPARATE_ARRAY(params); + ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(EX(extra_named_params), name, param) { + if (UNEXPECTED(!zend_verify_variadic_arg_type(EX(func), arg_info, arg_num, param))) { + HANDLE_EXCEPTION(); + } + Z_TRY_ADDREF_P(param); + zend_hash_add_new(Z_ARRVAL_P(params), name, param); + } ZEND_HASH_FOREACH_END(); + } else if (zend_hash_num_elements(Z_ARRVAL_P(params)) == 0) { + GC_ADDREF(EX(extra_named_params)); + ZVAL_ARR(params, EX(extra_named_params)); } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } + SEPARATE_ARRAY(params); + ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(EX(extra_named_params), name, param) { + Z_TRY_ADDREF_P(param); + zend_hash_add_new(Z_ARRVAL_P(params), name, param); + } ZEND_HASH_FOREACH_END(); } - ZEND_VM_NEXT_OPCODE(); } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE SAVE_OPLINE(); - if (IS_CONST == IS_CONST) { - op1_str = Z_STR_P(op1); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - op1_str = zend_string_copy(Z_STR_P(op1)); - } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - op1_str = zval_get_string_func(op1); - } - if (IS_CONST == IS_CONST) { - op2_str = Z_STR_P(op2); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - op2_str = zend_string_copy(Z_STR_P(op2)); - } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - } - op2_str = zval_get_string_func(op2); - } - do { - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { - GC_ADDREF(op2_str); - } - } - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - zend_string_release_ex(op1_str, 0); - break; - } - } - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { - GC_ADDREF(op1_str); - } - } - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - zend_string_release_ex(op2_str, 0); - break; - } - } - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CONST != IS_CONST) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CONST != IS_CONST) { - zend_string_release_ex(op2_str, 0); - } - } while (0); + zval *result = EX_VAR(opline->result.var); + ZVAL_NULL(result); + zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R); + if (EG(exception)) { + FREE_OP(opline->op1_type, opline->op1.var); + HANDLE_EXCEPTION(); + } +#if 0 || 0 + if (0 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) { + zend_frameless_observed_call(execute_data); + } else +#endif + { + zend_frameless_function_1 function = (zend_frameless_function_1)ZEND_FLF_HANDLER(opline); + function(result, arg1); + } + FREE_OP(opline->op1_type, opline->op1.var); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FRAMELESS_ICALL_1_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + SAVE_OPLINE(); + zval *result = EX_VAR(opline->result.var); + ZVAL_NULL(result); + zval *arg1 = get_zval_ptr_deref(opline->op1_type, opline->op1, BP_VAR_R); + if (EG(exception)) { + FREE_OP(opline->op1_type, opline->op1.var); + HANDLE_EXCEPTION(); + } +#if 0 || 1 + if (1 && UNEXPECTED(zend_observer_handler_is_unobserved(ZEND_OBSERVER_DATA(ZEND_FLF_FUNC(opline))) == false)) { + zend_frameless_observed_call(execute_data); + } else +#endif + { + zend_frameless_function_1 function = (zend_frameless_function_1)ZEND_FLF_HANDLER(opline); + function(result, arg1); + } + FREE_OP(opline->op1_type, opline->op1.var); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_DYNAMIC_CALL_SPEC_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; - zval *object; - zend_function *fbc; - zend_class_entry *called_scope; - zend_object *obj; zend_execute_data *call; - uint32_t call_info; SAVE_OPLINE(); + function_name = EX_VAR(opline->op2.var); - object = RT_CONSTANT(opline, opline->op1); - - if (IS_CONST != IS_CONST) { - function_name = RT_CONSTANT(opline, opline->op2); +try_function_name: + if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + call = zend_init_dynamic_call_string(Z_STR_P(function_name), opline->extended_value); + } else if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT)) { + call = zend_init_dynamic_call_object(Z_OBJ_P(function_name), opline->extended_value); + } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY)) { + call = zend_init_dynamic_call_array(Z_ARRVAL_P(function_name), opline->extended_value); + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(function_name) == IS_REFERENCE)) { + function_name = Z_REFVAL_P(function_name); + goto try_function_name; + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + function_name = ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Value of type %s is not callable", + zend_zval_type_name(function_name)); + call = NULL; } - if (IS_CONST != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_CV & (IS_VAR|IS_TMP_VAR)) { - HANDLE_EXCEPTION(); + if (UNEXPECTED(EG(exception))) { + if (call) { + if (call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) { + zend_string_release_ex(call->func->common.function_name, 0); + zend_free_trampoline(call->func); } + zend_vm_stack_free_call_frame(call); } - zend_throw_error(NULL, "Method name must be a string"); + HANDLE_EXCEPTION(); + } + } else if (!call) { + HANDLE_EXCEPTION(); + } + call->prev_execute_data = EX(call); + EX(call) = call; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_NOT_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1; - HANDLE_EXCEPTION(); - } while (0); + op1 = RT_CONSTANT(opline, opline->op1); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), ~Z_LVAL_P(op1)); + ZEND_VM_NEXT_OPCODE(); } - if (IS_CONST == IS_UNUSED) { - obj = Z_OBJ_P(object); + ZEND_VM_DISPATCH_TO_HELPER(zend_bw_not_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1)); +} + +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_NOT_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val; + + val = RT_CONSTANT(opline, opline->op1); + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + /* The result and op1 can be the same cv zval */ + const uint32_t orig_val_type = Z_TYPE_INFO_P(val); + ZVAL_TRUE(EX_VAR(opline->result.var)); + if (IS_CONST == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } } else { - do { - if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - } else { - if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - zend_reference *ref = Z_REF_P(object); + SAVE_OPLINE(); + ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val)); - object = &ref->val; - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - if (IS_CONST & IS_VAR) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_ADDREF_P(object); - } - } - break; - } - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - object = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CONST != IS_CONST) { + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + ZEND_VM_NEXT_OPCODE(); +} - } - HANDLE_EXCEPTION(); - } - } - if (IS_CONST == IS_CONST) { - function_name = RT_CONSTANT(opline, opline->op2); - } - zend_invalid_method_call(object, function_name); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ECHO_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *z; + SAVE_OPLINE(); + z = RT_CONSTANT(opline, opline->op1); + if (Z_TYPE_P(z) == IS_STRING) { + zend_string *str = Z_STR_P(z); + if (ZSTR_LEN(str) != 0) { + zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); + } + } else { + zend_string *str = zval_get_string_func(z); - HANDLE_EXCEPTION(); - } - } while (0); + if (ZSTR_LEN(str) != 0) { + zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_string_release_ex(str, 0); } - called_scope = obj->ce; - if (IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else { - zend_object *orig_obj = obj; + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - if (IS_CONST == IS_CONST) { - function_name = RT_CONSTANT(opline, opline->op2); - } +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPZ_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val; + uint8_t op1_type; - /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); + val = RT_CONSTANT(opline, opline->op1); + + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); } + } + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } + + SAVE_OPLINE(); + op1_type = IS_CONST; + if (i_zend_is_true(val)) { + opline++; + } else { + opline = OP_JMP_ADDR(opline, opline->op2); + } + if (op1_type & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_nogc(val); + } + ZEND_VM_JMP(opline); +} + +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPNZ_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val; + uint8_t op1_type; + val = RT_CONSTANT(opline, opline->op1); - if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); } - HANDLE_EXCEPTION(); - } - if (IS_CONST == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); } - if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ - if (GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + op1_type = IS_CONST; + if (i_zend_is_true(val)) { + opline = OP_JMP_ADDR(opline, opline->op2); + } else { + opline++; + } + if (op1_type & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_nogc(val); + } + ZEND_VM_JMP(opline); +} + +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPZ_EX_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val; + bool ret; + + val = RT_CONSTANT(opline, opline->op1); + + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); } } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } - if (IS_CONST != IS_CONST) { + SAVE_OPLINE(); + ret = i_zend_is_true(val); + if (ret) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + opline++; + } else { + ZVAL_FALSE(EX_VAR(opline->result.var)); + opline = OP_JMP_ADDR(opline, opline->op2); } + ZEND_VM_JMP(opline); +} - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { - zend_objects_store_del(obj); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - /* call static method */ - obj = (zend_object*)called_scope; - call_info = ZEND_CALL_NESTED_FUNCTION; - } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { - if (IS_CONST == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPNZ_EX_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val; + bool ret; + + val = RT_CONSTANT(opline, opline->op1); + + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); } - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, obj); - call->prev_execute_data = EX(call); - EX(call) = call; + SAVE_OPLINE(); + ret = i_zend_is_true(val); - ZEND_VM_NEXT_OPCODE(); + + if (ret) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + opline = OP_JMP_ADDR(opline, opline->op2); + } else { + ZVAL_FALSE(EX_VAR(opline->result.var)); + opline++; + } + ZEND_VM_JMP(opline); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zend_class_entry *ce; - uint32_t call_info; - zend_function *fbc; - zend_execute_data *call; + zval *retval_ptr; + zval *return_value; - SAVE_OPLINE(); - if (IS_CONST == IS_CONST) { - /* no function found. try a static method in class */ - ce = CACHED_PTR(opline->result.num); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { + retval_ptr = RT_CONSTANT(opline, opline->op1); + return_value = EX(return_value); - HANDLE_EXCEPTION(); - } - if (IS_CONST != IS_CONST) { - CACHE_PTR(opline->result.num, ce); - } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) { + SAVE_OPLINE(); + retval_ptr = ZVAL_UNDEFINED_OP1(); + if (return_value) { + ZVAL_NULL(return_value); } - } else if (IS_CONST == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - - - HANDLE_EXCEPTION(); + } else if (!return_value) { + if (IS_CONST & (IS_VAR|IS_TMP_VAR)) { + if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) { + SAVE_OPLINE(); + rc_dtor_func(Z_COUNTED_P(retval_ptr)); + } } } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - - if (IS_CONST == IS_CONST && - IS_CONST == IS_CONST && - EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { - /* nothing to do */ - } else if (IS_CONST != IS_CONST && - IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else if (IS_CONST != IS_UNUSED) { - function_name = RT_CONSTANT(opline, opline->op2); - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if (IS_CONST & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { + ZVAL_COPY_VALUE(return_value, retval_ptr); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) { + Z_ADDREF_P(return_value); + } + } + } else if (IS_CONST == IS_CV) { + do { + if (Z_OPT_REFCOUNTED_P(retval_ptr)) { + if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { + if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + ZVAL_COPY_VALUE(return_value, retval_ptr); + if (GC_MAY_LEAK(ref)) { + SAVE_OPLINE(); + gc_possible_root(ref); + } + ZVAL_NULL(retval_ptr); break; + } else { + Z_ADDREF_P(retval_ptr); } - } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + } else { + retval_ptr = Z_REFVAL_P(retval_ptr); + if (Z_OPT_REFCOUNTED_P(retval_ptr)) { + Z_ADDREF_P(retval_ptr); } } - zend_throw_error(NULL, "Method name must be a string"); - + } + ZVAL_COPY_VALUE(return_value, retval_ptr); + } while (0); + } else /* if (IS_CONST == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(retval_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); - HANDLE_EXCEPTION(); - } while (0); + retval_ptr = Z_REFVAL_P(retval_ptr); + ZVAL_COPY_VALUE(return_value, retval_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { + Z_ADDREF_P(retval_ptr); + } + } else { + ZVAL_COPY_VALUE(return_value, retval_ptr); } } + } - if (ce->get_static_method) { - fbc = ce->get_static_method(ce, Z_STR_P(function_name)); - } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - } - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(ce, Z_STR_P(function_name)); - } - HANDLE_EXCEPTION(); - } - if (IS_CONST == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { - CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - if (IS_CONST != IS_CONST) { - } - } else { - if (UNEXPECTED(ce->constructor == NULL)) { - zend_throw_error(NULL, "Cannot call constructor"); - HANDLE_EXCEPTION(); - } - if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { - zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); - HANDLE_EXCEPTION(); - } - fbc = ce->constructor; - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - } - if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { - if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - ce = (zend_class_entry*)Z_OBJ(EX(This)); - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - } else { - zend_non_static_method_call(fbc); - HANDLE_EXCEPTION(); + ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); +} + +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *retval_ptr; + zval *return_value; + zval observer_retval; + + retval_ptr = get_zval_ptr_undef(opline->op1_type, opline->op1, BP_VAR_R); + return_value = EX(return_value); + if (!return_value) { return_value = &observer_retval; }; + if (opline->op1_type == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) { + SAVE_OPLINE(); + retval_ptr = ZVAL_UNDEFINED_OP1(); + if (return_value) { + ZVAL_NULL(return_value); + } + } else if (!return_value) { + if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) { + if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) { + SAVE_OPLINE(); + rc_dtor_func(Z_COUNTED_P(retval_ptr)); + } } } else { - /* previous opcode is ZEND_FETCH_CLASS */ - if (IS_CONST == IS_UNUSED - && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { - if (Z_TYPE(EX(This)) == IS_OBJECT) { - ce = Z_OBJCE(EX(This)); + if ((opline->op1_type & (IS_CONST|IS_TMP_VAR))) { + ZVAL_COPY_VALUE(return_value, retval_ptr); + if (opline->op1_type == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) { + Z_ADDREF_P(return_value); + } + } + } else if (opline->op1_type == IS_CV) { + do { + if (Z_OPT_REFCOUNTED_P(retval_ptr)) { + if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { + if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + ZVAL_COPY_VALUE(return_value, retval_ptr); + if (GC_MAY_LEAK(ref)) { + SAVE_OPLINE(); + gc_possible_root(ref); + } + ZVAL_NULL(retval_ptr); + break; + } else { + Z_ADDREF_P(retval_ptr); + } + } else { + retval_ptr = Z_REFVAL_P(retval_ptr); + if (Z_OPT_REFCOUNTED_P(retval_ptr)) { + Z_ADDREF_P(retval_ptr); + } + } + } + ZVAL_COPY_VALUE(return_value, retval_ptr); + } while (0); + } else /* if (opline->op1_type == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(retval_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + + retval_ptr = Z_REFVAL_P(retval_ptr); + ZVAL_COPY_VALUE(return_value, retval_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { + Z_ADDREF_P(retval_ptr); + } } else { - ce = Z_CE(EX(This)); + ZVAL_COPY_VALUE(return_value, retval_ptr); } } - call_info = ZEND_CALL_NESTED_FUNCTION; } - - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, ce); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + zend_observer_fcall_end(execute_data, return_value); + if (return_value == &observer_retval) { zval_ptr_dtor_nogc(&observer_retval); }; + ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_USER_CALL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_BY_REF_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zend_fcall_info_cache fcc; - char *error = NULL; - zend_function *func; - void *object_or_called_scope; - zend_execute_data *call; - uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; + zval *retval_ptr; + zval *return_value; + SAVE_OPLINE(); - function_name = RT_CONSTANT(opline, opline->op2); - if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { - ZEND_ASSERT(!error); - /* Deprecation can be emitted from zend_is_callable_ex(), which can - * invoke a user error handler and throw an exception. - * For the CONST and CV case we reuse the same exception block below - * to make sure we don't increase VM size too much. */ - if (!(IS_CONST & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { + return_value = EX(return_value); - HANDLE_EXCEPTION(); - } + do { + if ((IS_CONST & (IS_CONST|IS_TMP_VAR)) || + (IS_CONST == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { + /* Not supposed to happen, but we'll allow it */ + zend_error(E_NOTICE, "Only variable references should be returned by reference"); - func = fcc.function_handler; - object_or_called_scope = fcc.called_scope; - if (func->common.fn_flags & ZEND_ACC_CLOSURE) { - /* Delay closure destruction until its invocation */ - GC_ADDREF(ZEND_CLOSURE_OBJECT(func)); - call_info |= ZEND_CALL_CLOSURE; - if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { - call_info |= ZEND_CALL_FAKE_CLOSURE; - } - if (fcc.object) { - object_or_called_scope = fcc.object; - call_info |= ZEND_CALL_HAS_THIS; + retval_ptr = RT_CONSTANT(opline, opline->op1); + if (!return_value) { + + + } else { + if (IS_CONST == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) { + ZVAL_COPY_VALUE(return_value, retval_ptr); + break; + } + + ZVAL_NEW_REF(return_value, retval_ptr); + if (IS_CONST == IS_CONST) { + Z_TRY_ADDREF_P(retval_ptr); + } } - } else if (fcc.object) { - GC_ADDREF(fcc.object); /* For $this pointer */ - object_or_called_scope = fcc.object; - call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS; + break; } + retval_ptr = zend_get_bad_ptr(); - if ((IS_CONST & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { - if (call_info & ZEND_CALL_CLOSURE) { - zend_object_release(ZEND_CLOSURE_OBJECT(func)); - } else if (call_info & ZEND_CALL_RELEASE_THIS) { - zend_object_release(fcc.object); + if (IS_CONST == IS_VAR) { + ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) { + zend_error(E_NOTICE, "Only variable references should be returned by reference"); + if (return_value) { + ZVAL_NEW_REF(return_value, retval_ptr); + } else { + + + } + break; } - HANDLE_EXCEPTION(); } - if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&func->op_array))) { - init_func_run_time_cache(&func->op_array); + if (return_value) { + if (Z_ISREF_P(retval_ptr)) { + Z_ADDREF_P(retval_ptr); + } else { + ZVAL_MAKE_REF_EX(retval_ptr, 2); + } + ZVAL_REF(return_value, Z_REF_P(retval_ptr)); } - } else { - zend_type_error("%s(): Argument #1 ($callback) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error); - efree(error); - - - HANDLE_EXCEPTION(); - } - call = zend_vm_stack_push_call_frame(call_info, - func, opline->extended_value, object_or_called_scope); - call->prev_execute_data = EX(call); - EX(call) = call; - ZEND_VM_NEXT_OPCODE(); -} + } while (0); -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value, *arg; - if (IS_CONST == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - uint32_t arg_num; - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - } + // FIXME: Don't create the ref in the first place? + zend_return_unwrap_ref(execute_data, return_value); - value = RT_CONSTANT(opline, opline->op1); - ZVAL_COPY_VALUE(arg, value); - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { - Z_ADDREF_P(arg); - } - } - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_EX_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_BY_REF_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value, *arg; - uint32_t arg_num; + zval *retval_ptr; + zval *return_value; + zval observer_retval; - if (IS_CONST == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { + SAVE_OPLINE(); + return_value = EX(return_value); + if (!return_value) { return_value = &observer_retval; }; + do { + if ((opline->op1_type & (IS_CONST|IS_TMP_VAR)) || + (opline->op1_type == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { + /* Not supposed to happen, but we'll allow it */ + zend_error(E_NOTICE, "Only variable references should be returned by reference"); - HANDLE_EXCEPTION(); + retval_ptr = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R); + if (!return_value) { + FREE_OP(opline->op1_type, opline->op1.var); + } else { + if (opline->op1_type == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) { + ZVAL_COPY_VALUE(return_value, retval_ptr); + break; + } + + ZVAL_NEW_REF(return_value, retval_ptr); + if (opline->op1_type == IS_CONST) { + Z_TRY_ADDREF_P(retval_ptr); + } + } + break; } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - arg_num = opline->op2.num; - } - if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) { - if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - goto send_val_by_ref; + retval_ptr = get_zval_ptr_ptr(opline->op1_type, opline->op1, BP_VAR_W); + + if (opline->op1_type == IS_VAR) { + ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) { + zend_error(E_NOTICE, "Only variable references should be returned by reference"); + if (return_value) { + ZVAL_NEW_REF(return_value, retval_ptr); + } else { + FREE_OP(opline->op1_type, opline->op1.var); + } + break; + } } - } else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { -send_val_by_ref:; - ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg)); - } - value = RT_CONSTANT(opline, opline->op1); - ZVAL_COPY_VALUE(arg, value); - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { - Z_ADDREF_P(arg); + + if (return_value) { + if (Z_ISREF_P(retval_ptr)) { + Z_ADDREF_P(retval_ptr); + } else { + ZVAL_MAKE_REF_EX(retval_ptr, 2); + } + ZVAL_REF(return_value, Z_REF_P(retval_ptr)); } - } - ZEND_VM_NEXT_OPCODE(); + + FREE_OP(opline->op1_type, opline->op1.var); + } while (0); + + zend_observer_fcall_end(execute_data, return_value); + if (return_value == &observer_retval) { zval_ptr_dtor_nogc(&observer_retval); }; + + // FIXME: Don't create the ref in the first place? + zend_return_unwrap_ref(execute_data, return_value); + + ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GENERATOR_RETURN_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zend_class_entry *ce, *scope; - zend_class_constant *c; - zval *value, *zv, *constant_zv; - zend_string *constant_name; USE_OPLINE + zval *retval; + + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); SAVE_OPLINE(); + retval = RT_CONSTANT(opline, opline->op1); - do { - if (IS_CONST == IS_CONST && IS_CONST == IS_CONST) { - if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) { - value = CACHED_PTR(opline->extended_value + sizeof(void*)); - break; - } - } + /* Copy return value into generator->retval */ + if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { + ZVAL_COPY_VALUE(&generator->retval, retval); if (IS_CONST == IS_CONST) { - if (EXPECTED(CACHED_PTR(opline->extended_value))) { - ce = CACHED_PTR(opline->extended_value); - } else { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - - - HANDLE_EXCEPTION(); - } - CACHE_PTR(opline->extended_value, ce); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) { + Z_ADDREF(generator->retval); } - } else if (IS_CONST == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - + } + } else if (IS_CONST == IS_CV) { + ZVAL_COPY_DEREF(&generator->retval, retval); + } else /* if (IS_CONST == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_refcounted *ref = Z_COUNTED_P(retval); - HANDLE_EXCEPTION(); + retval = Z_REFVAL_P(retval); + ZVAL_COPY_VALUE(&generator->retval, retval); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(retval)) { + Z_ADDREF_P(retval); } } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - if (IS_CONST != IS_CONST - && IS_CONST == IS_CONST - && EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { - value = CACHED_PTR(opline->extended_value + sizeof(void*)); - break; + ZVAL_COPY_VALUE(&generator->retval, retval); } + } - constant_zv = RT_CONSTANT(opline, opline->op2); - if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) { - zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); + EG(current_execute_data) = EX(prev_execute_data); - HANDLE_EXCEPTION(); - } - constant_name = Z_STR_P(constant_zv); - /* Magic 'class' for constant OP2 is caught at compile-time */ - if (IS_CONST != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); + /* Close the generator to free up resources */ + zend_generator_close(generator, 1); + /* Pass execution back to handling code */ + ZEND_VM_RETURN(); +} - ZEND_VM_NEXT_OPCODE(); - } - zv = IS_CONST == IS_CONST - ? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name) - : zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GENERATOR_RETURN_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *retval; - if (EXPECTED(zv != NULL)) { - c = Z_PTR_P(zv); - scope = EX(func)->op_array.scope; - if (!zend_verify_const_access(c, scope)) { - zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + SAVE_OPLINE(); + retval = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R); - HANDLE_EXCEPTION(); + /* Copy return value into generator->retval */ + if ((opline->op1_type & (IS_CONST|IS_TMP_VAR))) { + ZVAL_COPY_VALUE(&generator->retval, retval); + if (opline->op1_type == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) { + Z_ADDREF(generator->retval); } + } + } else if (opline->op1_type == IS_CV) { + ZVAL_COPY_DEREF(&generator->retval, retval); + } else /* if (opline->op1_type == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_refcounted *ref = Z_COUNTED_P(retval); - if (ce->ce_flags & ZEND_ACC_TRAIT) { - zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - - - HANDLE_EXCEPTION(); + retval = Z_REFVAL_P(retval); + ZVAL_COPY_VALUE(&generator->retval, retval); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(retval)) { + Z_ADDREF_P(retval); } + } else { + ZVAL_COPY_VALUE(&generator->retval, retval); + } + } - bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; - if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) { - if (c->ce->type == ZEND_USER_CLASS) { - /* Recursion protection only applied to user constants, GH-18463 */ - CONST_PROTECT_RECURSION(c); - } - zend_deprecated_class_constant(c, constant_name); - if (c->ce->type == ZEND_USER_CLASS) { - CONST_UNPROTECT_RECURSION(c); - } + zend_observer_fcall_end(generator->execute_data, &generator->retval); - if (EG(exception)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); + EG(current_execute_data) = EX(prev_execute_data); + /* Close the generator to free up resources */ + zend_generator_close(generator, 1); - HANDLE_EXCEPTION(); - } - } + /* Pass execution back to handling code */ + ZEND_VM_RETURN(); +} - value = &c->value; - // Enums require loading of all class constants to build the backed enum table - if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { - if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_THROW_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + SAVE_OPLINE(); + value = RT_CONSTANT(opline, opline->op1); - HANDLE_EXCEPTION(); + do { + if (IS_CONST == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + value = Z_REFVAL_P(value); + if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { + break; } } - if (Z_TYPE_P(value) == IS_CONSTANT_AST) { - if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - - + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } } - if (IS_CONST == IS_CONST && !is_constant_deprecated) { - CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); - } - } else { - zend_throw_error(NULL, "Undefined constant %s::%s", - ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); + zend_throw_error(NULL, "Can only throw objects"); HANDLE_EXCEPTION(); } } while (0); - ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); + zend_exception_save(); + Z_TRY_ADDREF_P(value); + zend_throw_exception_object(value); + zend_exception_restore(); - ZEND_VM_NEXT_OPCODE(); + HANDLE_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CATCH_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *expr_ptr, new_expr; + zend_class_entry *ce, *catch_ce; + zend_object *exception; SAVE_OPLINE(); - if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && - UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = zend_get_bad_ptr(); - if (Z_ISREF_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } else { - ZVAL_MAKE_REF_EX(expr_ptr, 2); - } + /* Check whether an exception has been thrown, if not, jump over code */ + zend_exception_restore(); + if (EG(exception) == NULL) { + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } + catch_ce = CACHED_PTR(opline->extended_value & ~ZEND_LAST_CATCH); + if (UNEXPECTED(catch_ce == NULL)) { + catch_ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT); + CACHE_PTR(opline->extended_value & ~ZEND_LAST_CATCH, catch_ce); + } + ce = EG(exception)->ce; - } else { - expr_ptr = RT_CONSTANT(opline, opline->op1); - if (IS_CONST == IS_TMP_VAR) { - /* pass */ - } else if (IS_CONST == IS_CONST) { - Z_TRY_ADDREF_P(expr_ptr); - } else if (IS_CONST == IS_CV) { - ZVAL_DEREF(expr_ptr); - Z_TRY_ADDREF_P(expr_ptr); - } else /* if (IS_CONST == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(expr_ptr); +#ifdef HAVE_DTRACE + if (DTRACE_EXCEPTION_CAUGHT_ENABLED()) { + DTRACE_EXCEPTION_CAUGHT((char *)ce->name); + } +#endif /* HAVE_DTRACE */ - expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - ZVAL_COPY_VALUE(&new_expr, expr_ptr); - expr_ptr = &new_expr; - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } + if (ce != catch_ce) { + if (!catch_ce || !instanceof_function(ce, catch_ce)) { + if (opline->extended_value & ZEND_LAST_CATCH) { + zend_rethrow_exception(execute_data); + HANDLE_EXCEPTION(); } + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } } - if (IS_CONST != IS_UNUSED) { - zval *offset = RT_CONSTANT(opline, opline->op2); - zend_string *str; - zend_ulong hval; + exception = EG(exception); + EG(exception) = NULL; + if (RETURN_VALUE_USED(opline)) { + /* Always perform a strict assignment. There is a reasonable expectation that if you + * write "catch (Exception $e)" then $e will actually be instanceof Exception. As such, + * we should not permit coercion to string here. */ + zval tmp; + ZVAL_OBJ(&tmp, exception); + zend_assign_to_variable(EX_VAR(opline->result.var), &tmp, IS_TMP_VAR, /* strict */ 1); + } else { + OBJ_RELEASE(exception); + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} -add_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_CONST != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index; - } - } -str_index: - zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index: - zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto add_again; - } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { - zval tmp; - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_COPY(&tmp, expr_ptr); - } - zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - /* A userland error handler can do funky things to the expression, so reset it */ - zval_ptr_dtor(expr_ptr); - ZVAL_COPY_VALUE(expr_ptr, &tmp); - } - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(expr_ptr); - HANDLE_EXCEPTION(); - } - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); - goto num_index; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - zend_use_resource_as_offset(offset); - hval = Z_RES_HANDLE_P(offset); - goto num_index; - } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else { - zend_illegal_array_offset_access(offset); - zval_ptr_dtor_nogc(expr_ptr); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_USER_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *arg, *param; + SAVE_OPLINE(); + arg = RT_CONSTANT(opline, opline->op1); + param = ZEND_CALL_VAR(EX(call), opline->result.var); + if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) { + zend_param_must_be_ref(EX(call)->func, opline->op2.num); + Z_TRY_ADDREF_P(arg); + ZVAL_NEW_REF(param, arg); } else { - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { - zend_cannot_add_element(); - zval_ptr_dtor_nogc(expr_ptr); - } + ZVAL_COPY(param, arg); } + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zval *array; - uint32_t size; USE_OPLINE + zval *val; - SAVE_OPLINE(); - array = EX_VAR(opline->result.var); - if (IS_CONST != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + val = RT_CONSTANT(opline, opline->op1); + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + /* The result and op1 can be the same cv zval */ + const uint32_t orig_val_type = Z_TYPE_INFO_P(val); + ZVAL_FALSE(EX_VAR(opline->result.var)); + if (IS_CONST == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZVAL_ARR(array, zend_new_array(0)); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CLONE_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - bool result; - zend_ulong hval; - zval *offset; + zval *obj; + zend_object *zobj; + zend_class_entry *ce, *scope; + zend_function *clone; + zend_object_clone_obj_t clone_call; SAVE_OPLINE(); - container = RT_CONSTANT(opline, opline->op1); - offset = RT_CONSTANT(opline, opline->op2); + obj = RT_CONSTANT(opline, opline->op1); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; - zval *value; - zend_string *str; + /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. + * The OPcode intentionally does not support a clone-with property list to keep it simple. */ -isset_dim_obj_array: - ht = Z_ARRVAL_P(container); -isset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_CONST != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index_prop; + do { + if (IS_CONST == IS_CONST || + (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) { + obj = Z_REFVAL_P(obj); + if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) { + break; } } - value = zend_hash_find_ex(ht, str, IS_CONST == IS_CONST); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_prop: - value = zend_hash_index_find(ht, hval); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { - offset = Z_REFVAL_P(offset); - goto isset_again; - } else { - value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); - if (UNEXPECTED(EG(exception))) { - result = 0; - goto isset_dim_obj_exit; + ZVAL_UNDEF(EX_VAR(opline->result.var)); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } } + zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj)); + + + HANDLE_EXCEPTION(); } + } while (0); - if (!(opline->extended_value & ZEND_ISEMPTY)) { - /* > IS_NULL means not IS_UNDEF and not IS_NULL */ - result = value != NULL && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + zobj = Z_OBJ_P(obj); + ce = zobj->ce; + clone = ce->clone; + clone_call = zobj->handlers->clone_obj; + if (UNEXPECTED(clone_call == NULL)) { + zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); - if (IS_CONST & (IS_CONST|IS_CV)) { - /* avoid exception check */ + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + + if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) { + scope = EX(func)->op_array.scope; + ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC)); + if (!zend_check_method_accessible(clone, scope)) { + zend_bad_method_call(clone, clone->common.function_name, scope); - ZEND_VM_SMART_BRANCH(result, 0); - } - } else { - result = (value == NULL || !i_zend_is_true(value)); - } - goto isset_dim_obj_exit; - } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto isset_dim_obj_array; + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } } - if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - if (!(opline->extended_value & ZEND_ISEMPTY)) { - result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); - } else { - result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); - } + ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CAST_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *expr; + zval *result = EX_VAR(opline->result.var); + + SAVE_OPLINE(); + expr = RT_CONSTANT(opline, opline->op1); + + switch (opline->extended_value) { + case IS_LONG: + ZVAL_LONG(result, zval_get_long(expr)); + break; + case IS_DOUBLE: + ZVAL_DOUBLE(result, zval_get_double(expr)); + break; + case IS_STRING: + ZVAL_STR(result, zval_get_string(expr)); + break; + default: + ZEND_ASSERT(opline->extended_value != _IS_BOOL && "Must use ZEND_BOOL instead"); + if (IS_CONST & (IS_VAR|IS_CV)) { + ZVAL_DEREF(expr); + } + /* If value is already of correct type, return it directly */ + if (Z_TYPE_P(expr) == opline->extended_value) { + ZVAL_COPY_VALUE(result, expr); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); + } else if (IS_CONST != IS_TMP_VAR) { + if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); + } -isset_dim_obj_exit: + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + if (opline->extended_value == IS_ARRAY) { + zend_cast_zval_to_array(result, expr, IS_CONST); + } else { + ZEND_ASSERT(opline->extended_value == IS_OBJECT); + zend_cast_zval_to_object(result, expr, IS_CONST); + } + } - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - int result; - zval *offset; - zend_string *name, *tmp_name; + zend_op_array *new_op_array; + zval *inc_filename; SAVE_OPLINE(); - container = RT_CONSTANT(opline, opline->op1); - offset = RT_CONSTANT(opline, opline->op2); + inc_filename = RT_CONSTANT(opline, opline->op1); + new_op_array = zend_include_or_eval(inc_filename, opline->extended_value); + if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CONST == IS_CONST || - (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } - } else { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; + + if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) { + destroy_op_array(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); } - } + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else if (new_op_array == ZEND_FAKE_OP_ARRAY) { + if (RETURN_VALUE_USED(opline)) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + } + } else if (UNEXPECTED(new_op_array == NULL)) { + if (RETURN_VALUE_USED(opline)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + } + } else if (new_op_array->last == 1 + && new_op_array->opcodes[0].opcode == ZEND_RETURN + && new_op_array->opcodes[0].op1_type == IS_CONST + && EXPECTED(zend_execute_ex == execute_ex)) { + if (RETURN_VALUE_USED(opline)) { + const zend_op *op = new_op_array->opcodes; - if (IS_CONST == IS_CONST) { - name = Z_STR_P(offset); + ZVAL_COPY(EX_VAR(opline->result.var), RT_CONSTANT(op, op->op1)); + } + zend_destroy_static_vars(new_op_array); + destroy_op_array(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - result = 0; - goto isset_object_finish; + zval *return_value = NULL; + zend_execute_data *call; + if (RETURN_VALUE_USED(opline)) { + return_value = EX_VAR(opline->result.var); } - } - - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + new_op_array->scope = EX(func)->op_array.scope; -isset_object_finish: + call = zend_vm_stack_push_call_frame( + (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, + (zend_function*)new_op_array, 0, + Z_PTR(EX(This))); + if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { + call->symbol_table = EX(symbol_table); + } else { + call->symbol_table = zend_rebuild_symbol_table(); + } + call->prev_execute_data = execute_data; + i_init_code_execute_data(call, new_op_array, return_value); - ZEND_VM_SMART_BRANCH(result, 1); -} + if (EXPECTED(zend_execute_ex == execute_ex)) { -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *key, *subject; - HashTable *ht; - bool result; + ZEND_VM_ENTER(); + } else { + ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); + zend_execute_ex(call); + zend_vm_stack_free_call_frame(call); + } - SAVE_OPLINE(); + zend_destroy_static_vars(new_op_array); + destroy_op_array(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); - key = RT_CONSTANT(opline, opline->op1); - subject = RT_CONSTANT(opline, opline->op2); - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { -array_key_exists_array: - ht = Z_ARRVAL_P(subject); - result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); - } else { - if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { - subject = Z_REFVAL_P(subject); - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { - goto array_key_exists_array; - } + UNDEF_RESULT(); + HANDLE_EXCEPTION(); } - zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); - result = 0; } - - - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zend_class_entry *ce = CACHED_PTR(opline->extended_value); - if (ce == NULL) { - zval *lcname = RT_CONSTANT(opline, opline->op1); - zval *zv = zend_hash_find_known_hash(EG(class_table), Z_STR_P(lcname + 1)); - if (zv) { - SAVE_OPLINE(); - ce = zend_bind_class_in_slot(zv, lcname, Z_STR_P(RT_CONSTANT(opline, opline->op2))); - if (EG(exception)) { - HANDLE_EXCEPTION(); - } - } - CACHE_PTR(opline->extended_value, ce); - } ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_CONST_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *name; - zval *val; - zend_constant c; + zend_op_array *new_op_array; + zval *inc_filename; SAVE_OPLINE(); - name = RT_CONSTANT(opline, opline->op1); - val = RT_CONSTANT(opline, opline->op2); + inc_filename = get_zval_ptr(opline->op1_type, opline->op1, BP_VAR_R); + new_op_array = zend_include_or_eval(inc_filename, opline->extended_value); + if (UNEXPECTED(EG(exception) != NULL)) { + FREE_OP(opline->op1_type, opline->op1.var); + if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) { + destroy_op_array(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); + } + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else if (new_op_array == ZEND_FAKE_OP_ARRAY) { + if (RETURN_VALUE_USED(opline)) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + } + } else if (UNEXPECTED(new_op_array == NULL)) { + if (RETURN_VALUE_USED(opline)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + } + } else if (new_op_array->last == 1 + && new_op_array->opcodes[0].opcode == ZEND_RETURN + && new_op_array->opcodes[0].op1_type == IS_CONST + && EXPECTED(zend_execute_ex == execute_ex)) { + if (RETURN_VALUE_USED(opline)) { + const zend_op *op = new_op_array->opcodes; - ZVAL_COPY(&c.value, val); - if (Z_OPT_CONSTANT(c.value)) { - if (UNEXPECTED(zval_update_constant_ex(&c.value, EX(func)->op_array.scope) != SUCCESS)) { - zval_ptr_dtor_nogc(&c.value); + ZVAL_COPY(EX_VAR(opline->result.var), RT_CONSTANT(op, op->op1)); + } + zend_destroy_static_vars(new_op_array); + destroy_op_array(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); + } else { + zval *return_value = NULL; + zend_execute_data *call; + if (RETURN_VALUE_USED(opline)) { + return_value = EX_VAR(opline->result.var); + } + new_op_array->scope = EX(func)->op_array.scope; + call = zend_vm_stack_push_call_frame( + (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, + (zend_function*)new_op_array, 0, + Z_PTR(EX(This))); + if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { + call->symbol_table = EX(symbol_table); + } else { + call->symbol_table = zend_rebuild_symbol_table(); + } - HANDLE_EXCEPTION(); + call->prev_execute_data = execute_data; + i_init_code_execute_data(call, new_op_array, return_value); + zend_observer_fcall_begin_specialized(call, false); + if (EXPECTED(zend_execute_ex == execute_ex)) { + FREE_OP(opline->op1_type, opline->op1.var); + ZEND_VM_ENTER(); + } else { + ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); + zend_execute_ex(call); + zend_vm_stack_free_call_frame(call); } - } - /* non persistent, case sensitive */ - ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT); - c.name = zend_string_copy(Z_STR_P(name)); - if (zend_register_constant(&c) == NULL) { + zend_destroy_static_vars(new_op_array); + destroy_op_array(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + FREE_OP(opline->op1_type, opline->op1.var); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } } - - - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + FREE_OP(opline->op1_type, opline->op1.var); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_R_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *name; - zval *val; - zend_constant c, *registered; + zval *array_ptr, *result; SAVE_OPLINE(); - name = RT_CONSTANT(opline, opline->op1); - val = RT_CONSTANT(opline, opline->op2); - ZVAL_COPY(&c.value, val); - if (Z_OPT_CONSTANT(c.value)) { - if (UNEXPECTED(zval_update_constant_ex(&c.value, EX(func)->op_array.scope) != SUCCESS)) { - zval_ptr_dtor_nogc(&c.value); + array_ptr = RT_CONSTANT(opline, opline->op1); + if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { + result = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(result, array_ptr); + if (IS_CONST != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) { + Z_ADDREF_P(array_ptr); + } + Z_FE_POS_P(result) = 0; + ZEND_VM_NEXT_OPCODE(); + } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { + zend_object *zobj = Z_OBJ_P(array_ptr); + if (!zobj->ce->get_iterator) { + if (UNEXPECTED(zend_object_is_lazy(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (UNEXPECTED(EG(exception))) { + UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - } - /* non persistent, case sensitive */ - ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT); - c.name = zend_string_copy(Z_STR_P(name)); + HANDLE_EXCEPTION(); + } + } + HashTable *properties = zobj->properties; + if (properties) { + if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(properties); + } + properties = zobj->properties = zend_array_dup(properties); + } + } else { + properties = zobj->handlers->get_properties(zobj); + } - registered = zend_register_constant(&c); - if (registered == NULL) { + result = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(result, array_ptr); + if (IS_CONST != IS_TMP_VAR) { + Z_ADDREF_P(array_ptr); + } + if (zend_hash_num_elements(properties) == 0) { + Z_FE_ITER_P(result) = (uint32_t) -1; + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + } - /* two opcodes used, second one is the data with attributes */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); - } + Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0); - HashTable *attributes = Z_PTR_P(get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1)); - ZEND_ASSERT(attributes != NULL); - zend_constant_add_attributes(registered, attributes); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } else if (is_empty) { + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } + } else { + zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; - /* two opcodes used, second one is the data with attributes */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_RW_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + zval *array_ptr, *array_ref; SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + + if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { + array_ref = array_ptr = zend_get_bad_ptr(); + if (Z_ISREF_P(array_ref)) { + array_ptr = Z_REFVAL_P(array_ref); + } + } else { + array_ref = array_ptr = RT_CONSTANT(opline, opline->op1); } - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); + if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { + if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { + if (array_ptr == array_ref) { + ZVAL_NEW_REF(array_ref, array_ref); + array_ptr = Z_REFVAL_P(array_ref); + } + Z_ADDREF_P(array_ref); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); + } else { + array_ref = EX_VAR(opline->result.var); + ZVAL_NEW_REF(array_ref, array_ptr); + array_ptr = Z_REFVAL_P(array_ref); + } + if (IS_CONST == IS_CONST) { + ZVAL_ARR(array_ptr, zend_array_dup(Z_ARRVAL_P(array_ptr))); + } else { + SEPARATE_ARRAY(array_ptr); + } + Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0); - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); - /* Set the new yielded value */ - if (IS_CONST != IS_UNUSED) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_CONST & (IS_CONST|IS_TMP_VAR)) { - zval *value; + ZEND_VM_NEXT_OPCODE(); + } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { + if (!Z_OBJCE_P(array_ptr)->get_iterator) { + zend_object *zobj = Z_OBJ_P(array_ptr); + HashTable *properties; + if (UNEXPECTED(zend_object_is_lazy(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (UNEXPECTED(EG(exception))) { + UNDEF_RESULT(); - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = RT_CONSTANT(opline, opline->op1); - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } + HANDLE_EXCEPTION(); + } + } + if (IS_CONST == IS_VAR || IS_CONST == IS_CV) { + if (array_ptr == array_ref) { + ZVAL_NEW_REF(array_ref, array_ref); + array_ptr = Z_REFVAL_P(array_ref); } + Z_ADDREF_P(array_ref); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); } else { - zval *value_ptr = zend_get_bad_ptr(); + array_ptr = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(array_ptr, array_ref); + } + if (Z_OBJ_P(array_ptr)->properties + && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(Z_OBJ_P(array_ptr)->properties); + } + Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); + } - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - do { - if (IS_CONST == IS_VAR) { - ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION - && !Z_ISREF_P(value_ptr)) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - ZVAL_COPY(&generator->value, value_ptr); - break; - } - } - if (Z_ISREF_P(value_ptr)) { - Z_ADDREF_P(value_ptr); - } else { - ZVAL_MAKE_REF_EX(value_ptr, 2); - } - ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); - } while (0); + properties = Z_OBJPROP_P(array_ptr); + if (zend_hash_num_elements(properties) == 0) { + Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1; + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } - } else { - zval *value = RT_CONSTANT(opline, opline->op1); - /* Consts, temporary variables and references need copying */ - if (IS_CONST == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } else if (IS_CONST == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } else if (is_empty) { + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CONST == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } + ZEND_VM_NEXT_OPCODE(); } } } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); + zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; + + + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } +} - /* Set the new yielded key */ - if (IS_CONST != IS_UNUSED) { - zval *key = RT_CONSTANT(opline, opline->op2); - if ((IS_CONST & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { - key = Z_REFVAL_P(key); +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_SET_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + zend_reference *ref = NULL; + bool ret; + + SAVE_OPLINE(); + value = RT_CONSTANT(opline, opline->op1); + + if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(value)) { + if (IS_CONST == IS_VAR) { + ref = Z_REF_P(value); } - ZVAL_COPY(&generator->key, key); + value = Z_REFVAL_P(value); + } + ret = i_zend_is_true(value); - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); + if (UNEXPECTED(EG(exception))) { + + + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + + if (ret) { + zval *result = EX_VAR(opline->result.var); + + ZVAL_COPY_VALUE(result, value); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); + } else if (IS_CONST == IS_CV) { + if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); + } else if (IS_CONST == IS_VAR && ref) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(result)) { + Z_ADDREF_P(result); + } } - } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); - } - - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); - } else { - generator->send_target = NULL; + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); - ZEND_VM_RETURN(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SWITCH_LONG_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COALESCE_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op, *jump_zv; - HashTable *jumptable; + zval *value; + zend_reference *ref = NULL; - op = RT_CONSTANT(opline, opline->op1); + SAVE_OPLINE(); + value = RT_CONSTANT(opline, opline->op1); - if (Z_TYPE_P(op) != IS_LONG) { - ZVAL_DEREF(op); - if (Z_TYPE_P(op) != IS_LONG) { - /* Wrong type, fall back to ZEND_CASE chain */ - ZEND_VM_NEXT_OPCODE(); + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + if (IS_CONST & IS_VAR) { + ref = Z_REF_P(value); } + value = Z_REFVAL_P(value); } - jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); - jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op)); - if (jump_zv != NULL) { - ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); - ZEND_VM_CONTINUE(); - } else { - /* default */ - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); + if (Z_TYPE_P(value) > IS_NULL) { + zval *result = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(result, value); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); + } else if (IS_CONST == IS_CV) { + if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); + } else if ((IS_CONST & IS_VAR) && ref) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(result)) { + Z_ADDREF_P(result); + } + } + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } + + if ((IS_CONST & IS_VAR) && ref) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } } + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SWITCH_STRING_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_NULL_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op, *jump_zv; - HashTable *jumptable; + zval *val, *result; - op = RT_CONSTANT(opline, opline->op1); + val = RT_CONSTANT(opline, opline->op1); - if (Z_TYPE_P(op) != IS_STRING) { - if (IS_CONST == IS_CONST) { - /* Wrong type, fall back to ZEND_CASE chain */ - ZEND_VM_NEXT_OPCODE(); - } else { - ZVAL_DEREF(op); - if (Z_TYPE_P(op) != IS_STRING) { - /* Wrong type, fall back to ZEND_CASE chain */ - ZEND_VM_NEXT_OPCODE(); + if (Z_TYPE_P(val) > IS_NULL) { + do { + if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + if (Z_TYPE_P(val) <= IS_NULL) { + + + break; + } } - } + ZEND_VM_NEXT_OPCODE(); + } while (0); } - jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); - jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), IS_CONST == IS_CONST); - if (jump_zv != NULL) { - ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); - ZEND_VM_CONTINUE(); + result = EX_VAR(opline->result.var); + uint32_t short_circuiting_type = opline->extended_value & ZEND_SHORT_CIRCUITING_CHAIN_MASK; + if (EXPECTED(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { + ZVAL_NULL(result); + if (IS_CONST == IS_CV + && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF) + && (opline->extended_value & ZEND_JMP_NULL_BP_VAR_IS) == 0 + ) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + } else if (short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { + ZVAL_FALSE(result); } else { - /* default */ - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); + ZEND_ASSERT(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); + ZVAL_TRUE(result); } + + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MATCH_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op, *jump_zv; - HashTable *jumptable; + zval *value; + zval *result = EX_VAR(opline->result.var); - op = RT_CONSTANT(opline, opline->op1); - jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); + value = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } -match_try_again: - if (Z_TYPE_P(op) == IS_LONG) { - jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op)); - } else if (Z_TYPE_P(op) == IS_STRING) { - jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), IS_CONST == IS_CONST); - } else if (Z_TYPE_P(op) == IS_REFERENCE) { - op = Z_REFVAL_P(op); - goto match_try_again; + if (IS_CONST == IS_CV) { + ZVAL_COPY_DEREF(result, value); + } else if (IS_CONST == IS_VAR) { + if (UNEXPECTED(Z_ISREF_P(value))) { + ZVAL_COPY_VALUE(result, Z_REFVAL_P(value)); + if (UNEXPECTED(Z_DELREF_P(value) == 0)) { + efree_size(Z_REF_P(value), sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(result)) { + Z_ADDREF_P(result); + } + } else { + ZVAL_COPY_VALUE(result, value); + } } else { - if (UNEXPECTED((IS_CONST & IS_CV) && Z_TYPE_P(op) == IS_UNDEF)) { - SAVE_OPLINE(); - op = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + ZVAL_COPY_VALUE(result, value); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) { + Z_ADDREF_P(result); } - goto match_try_again; } - - goto default_branch; } + ZEND_VM_NEXT_OPCODE(); +} - if (jump_zv != NULL) { - ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); - ZEND_VM_CONTINUE(); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_CLASS_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + SAVE_OPLINE(); + do_bind_class(RT_CONSTANT(opline, opline->op1), (opline->op2_type == IS_CONST) ? Z_STR_P(RT_CONSTANT(opline, opline->op2)) : NULL); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_function *func; + zval *object; + zend_class_entry *called_scope; + + func = (zend_function *) EX(func)->op_array.dynamic_func_defs[opline->op2.num]; + if (Z_TYPE(EX(This)) == IS_OBJECT) { + called_scope = Z_OBJCE(EX(This)); + if (UNEXPECTED((func->common.fn_flags & ZEND_ACC_STATIC) || + (EX(func)->common.fn_flags & ZEND_ACC_STATIC))) { + object = NULL; + } else { + object = &EX(This); + } } else { -default_branch: - /* default */ - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); + called_scope = Z_CE(EX(This)); + object = NULL; } + SAVE_OPLINE(); + zend_create_closure(EX_VAR(opline->result.var), func, + EX(func)->op_array.scope, called_scope, object); + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IN_ARRAY_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_FROM_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1; - HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); - zval *result; + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + zval *val; - op1 = RT_CONSTANT(opline, opline->op1); - if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_CONST == IS_CONST); - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - ZEND_VM_SMART_BRANCH(result, 0); + SAVE_OPLINE(); + val = RT_CONSTANT(opline, opline->op1); + + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator"); + + + UNDEF_RESULT(); + HANDLE_EXCEPTION(); } - if (opline->extended_value) { - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - ZEND_VM_SMART_BRANCH(result, 0); +yield_from_try_again: + if (Z_TYPE_P(val) == IS_ARRAY) { + ZVAL_COPY_VALUE(&generator->values, val); + if (Z_OPT_REFCOUNTED_P(val)) { + Z_ADDREF_P(val); } - SAVE_OPLINE(); - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - result = zend_hash_find(ht, Z_STR_P(op1)); + Z_FE_POS(generator->values) = 0; - ZEND_VM_SMART_BRANCH(result, 0); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - result = zend_hash_index_find(ht, Z_LVAL_P(op1)); + } else if (IS_CONST != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) { + zend_class_entry *ce = Z_OBJCE_P(val); + if (ce == zend_ce_generator) { + zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); + Z_ADDREF_P(val); - ZEND_VM_SMART_BRANCH(result, 0); - } - } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - } else if (Z_TYPE_P(op1) <= IS_FALSE) { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { + + if (UNEXPECTED(new_gen->execute_data == NULL)) { + zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); + zval_ptr_dtor(val); + UNDEF_RESULT(); HANDLE_EXCEPTION(); + } else if (Z_ISUNDEF(new_gen->retval)) { + if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) { + zend_throw_error(NULL, "Impossible to yield from the Generator being currently run"); + zval_ptr_dtor(val); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else { + zend_generator_yield_from(generator, new_gen); + } + } else { + if (RETURN_VALUE_USED(opline)) { + ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval); + } + ZEND_VM_NEXT_OPCODE(); } - } - result = zend_hash_find_known_hash(ht, ZSTR_EMPTY_ALLOC()); - ZEND_VM_SMART_BRANCH(result, 0); - } else { - zend_string *key; - zval key_tmp; + } else { + zend_object_iterator *iter = ce->get_iterator(ce, val, 0); - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - result = zend_hash_find(ht, Z_STR_P(op1)); + if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) { + if (!EG(exception)) { + zend_throw_error(NULL, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name)); + } + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } - ZEND_VM_SMART_BRANCH(result, 0); + iter->index = 0; + if (iter->funcs->rewind) { + iter->funcs->rewind(iter); + if (UNEXPECTED(EG(exception) != NULL)) { + OBJ_RELEASE(&iter->std); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } } + + ZVAL_OBJ(&generator->values, &iter->std); } + } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + goto yield_from_try_again; + } else { + zend_throw_error(NULL, "Can use \"yield from\" only with arrays and Traversables"); - SAVE_OPLINE(); - ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) { - ZVAL_STR(&key_tmp, key); - if (zend_compare(op1, &key_tmp) == 0) { + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } - ZEND_VM_SMART_BRANCH(1, 1); - } - } ZEND_HASH_FOREACH_END(); + /* This is the default return value + * when the expression is a Generator, it will be overwritten in zend_generator_resume() */ + if (RETURN_VALUE_USED(opline)) { + ZVAL_NULL(EX_VAR(opline->result.var)); } + /* This generator has no send target (though the generator we delegate to might have one) */ + generator->send_target = NULL; - ZEND_VM_SMART_BRANCH(0, 1); + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); + + ZEND_VM_RETURN(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_STRLEN_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; - double d1, d2; + zval *value; - op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - fast_long_add_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto add_double; + value = RT_CONSTANT(opline, opline->op1); + if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(value); } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -add_double: - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, d1 + d2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto add_double; + ZEND_VM_NEXT_OPCODE(); + } else { + bool strict; + + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) { + value = Z_REFVAL_P(value); + if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + + + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + value = ZVAL_UNDEFINED_OP1(); } + strict = EX_USES_STRICT_TYPES(); + do { + if (EXPECTED(!strict)) { + zend_string *str; + zval tmp; + + if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) { + zend_error(E_DEPRECATED, + "strlen(): Passing null to parameter #1 ($string) of type string is deprecated"); + ZVAL_LONG(EX_VAR(opline->result.var), 0); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + break; + } + + ZVAL_COPY(&tmp, value); + if (zend_parse_arg_str_weak(&tmp, &str, 1)) { + ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str)); + zval_ptr_dtor(&tmp); + break; + } + zval_ptr_dtor(&tmp); + } + if (!EG(exception)) { + zend_type_error("strlen(): Argument #1 ($string) must be of type string, %s given", zend_zval_value_name(value)); + } + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } while (0); } - ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_TYPE_CHECK_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; - double d1, d2; + zval *value; + int result = 0; - op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - fast_long_sub_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto sub_double; + value = RT_CONSTANT(opline, opline->op1); + if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { +type_check_resource: + if (opline->extended_value != MAY_BE_RESOURCE + || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) { + result = 1; } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -sub_double: - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, d1 - d2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto sub_double; + } else if ((IS_CONST & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) { + value = Z_REFVAL_P(value); + if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { + goto type_check_resource; + } + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + result = ((1 << IS_NULL) & opline->extended_value) != 0; + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); - ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MOD_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; + ZEND_VM_SMART_BRANCH(result, 1); + } else { + ZEND_VM_SMART_BRANCH(result, 0); + } +} - op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { - ZEND_VM_TAIL_CALL(zend_mod_by_zero_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) { - /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */ - ZVAL_LONG(result, 0); - } else { - ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2)); - } - ZEND_VM_NEXT_OPCODE(); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DEFINED_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_constant *c; + + c = CACHED_PTR(opline->extended_value); + if (EXPECTED(c != NULL)) { + if (!IS_SPECIAL_CACHE_VAL(c)) { +defined_true: + ZEND_VM_SMART_BRANCH_TRUE(); + } else if (EXPECTED(zend_hash_num_elements(EG(zend_constants)) == DECODE_SPECIAL_CACHE_NUM(c))) { +defined_false: + ZEND_VM_SMART_BRANCH_FALSE(); } } - - ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + if (zend_quick_check_constant(RT_CONSTANT(opline, opline->op1) OPLINE_CC EXECUTE_DATA_CC) != SUCCESS) { + CACHE_PTR(opline->extended_value, ENCODE_SPECIAL_CACHE_NUM(zend_hash_num_elements(EG(zend_constants)))); + goto defined_false; + } else { + goto defined_true; + } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SL_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_FRAMELESS_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - - op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) - && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { - /* Perform shift on unsigned numbers to get well-defined wrap behavior. */ - ZVAL_LONG(EX_VAR(opline->result.var), - (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2))); + zend_jmp_fl_result result = (uintptr_t)CACHED_PTR(opline->extended_value); +try_again: + if (EXPECTED(result == ZEND_JMP_FL_HIT)) { + OPLINE = OP_JMP_ADDR(opline, opline->op2); + ZEND_VM_CONTINUE(); + } else if (EXPECTED(result == ZEND_JMP_FL_MISS)) { ZEND_VM_NEXT_OPCODE(); + } else { + ZEND_ASSERT(result == ZEND_JMP_FL_UNPRIMED); + /* func_name refers to the function in the local namespace, e.g. foo\substr. */ + zval *func_name = (zval *)RT_CONSTANT(opline, opline->op1); + /* If it cannot be found locally, we must be referring to the global function. */ + zval *func = zend_hash_find_known_hash(EG(function_table), Z_STR_P(func_name)); + /* ZEND_JMP_FL_MISS = 1, ZEND_JMP_FL_HIT = 2 */ + result = (func == NULL) + 1; + CACHE_PTR(opline->extended_value, (void *)result); + goto try_again; } - - ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SR_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_LONG_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *value; - op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) - && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } + value = RT_CONSTANT(opline, opline->op1); + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(value)); + ZEND_VM_NEXT_OPCODE(); +} - ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + + value = RT_CONSTANT(opline, opline->op1); + ZVAL_DOUBLE(EX_VAR(opline->result.var), Z_DVAL_P(value)); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_NOREF_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *value; - op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { -is_smaller_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - } else { -is_smaller_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_smaller_double; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_smaller_double: - if (d1 < d2) { - goto is_smaller_true; - } else { - goto is_smaller_false; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_smaller_double; - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + value = RT_CONSTANT(opline, opline->op1); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_SIMPLE_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *value, *arg; - op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { -is_smaller_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - } else { -is_smaller_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_smaller_double; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_smaller_double: - if (d1 < d2) { - goto is_smaller_true; - } else { - goto is_smaller_false; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_smaller_double; - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + value = RT_CONSTANT(opline, opline->op1); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + ZVAL_COPY_VALUE(arg, value); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *value, *arg; + uint32_t arg_num = opline->op2.num; - op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { -is_smaller_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - } else { -is_smaller_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_smaller_double; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_smaller_double: - if (d1 < d2) { - goto is_smaller_true; - } else { - goto is_smaller_false; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_smaller_double; - } + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg)); } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + value = RT_CONSTANT(opline, opline->op1); + ZVAL_COPY_VALUE(arg, value); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *op1, *op2, *result; double d1, d2; op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { /* pass */ } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { -is_smaller_or_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } else { -is_smaller_or_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - ZVAL_FALSE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } + result = EX_VAR(opline->result.var); + fast_long_add_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { d1 = (double)Z_LVAL_P(op1); d2 = Z_DVAL_P(op2); - goto is_smaller_or_equal_double; + goto add_double; } } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { d1 = Z_DVAL_P(op1); d2 = Z_DVAL_P(op2); -is_smaller_or_equal_double: - if (d1 <= d2) { - goto is_smaller_or_equal_true; - } else { - goto is_smaller_or_equal_false; - } +add_double: + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, d1 + d2); + ZEND_VM_NEXT_OPCODE(); } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { d1 = Z_DVAL_P(op1); d2 = (double)Z_LVAL_P(op2); - goto is_smaller_or_equal_double; + goto add_double; } } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + + ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *op1, *op2, *result; double d1, d2; op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { /* pass */ } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { -is_smaller_or_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } else { -is_smaller_or_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); - ZVAL_FALSE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } + result = EX_VAR(opline->result.var); + fast_long_sub_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { d1 = (double)Z_LVAL_P(op1); d2 = Z_DVAL_P(op2); - goto is_smaller_or_equal_double; + goto sub_double; } } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { d1 = Z_DVAL_P(op1); d2 = Z_DVAL_P(op2); -is_smaller_or_equal_double: - if (d1 <= d2) { - goto is_smaller_or_equal_true; - } else { - goto is_smaller_or_equal_false; - } +sub_double: + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, d1 - d2); + ZEND_VM_NEXT_OPCODE(); } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { d1 = Z_DVAL_P(op1); d2 = (double)Z_LVAL_P(op2); - goto is_smaller_or_equal_double; + goto sub_double; } } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + + ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *op1, *op2, *result; double d1, d2; op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { /* pass */ } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { -is_smaller_or_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } else { -is_smaller_or_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); - ZVAL_FALSE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } + zend_long overflow; + + result = EX_VAR(opline->result.var); + ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); + Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; + ZEND_VM_NEXT_OPCODE(); } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { d1 = (double)Z_LVAL_P(op1); d2 = Z_DVAL_P(op2); - goto is_smaller_or_equal_double; + goto mul_double; } } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { d1 = Z_DVAL_P(op1); d2 = Z_DVAL_P(op2); -is_smaller_or_equal_double: - if (d1 <= d2) { - goto is_smaller_or_equal_true; - } else { - goto is_smaller_or_equal_false; - } +mul_double: + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, d1 * d2); + ZEND_VM_NEXT_OPCODE(); } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { d1 = Z_DVAL_P(op1); d2 = (double)Z_LVAL_P(op2); - goto is_smaller_or_equal_double; - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - zend_class_entry *ce, *scope; - zend_class_constant *c; - zval *value, *zv, *constant_zv; - zend_string *constant_name; - USE_OPLINE - - SAVE_OPLINE(); - - do { - if (IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) { - value = CACHED_PTR(opline->extended_value + sizeof(void*)); - break; - } - } - if (IS_CONST == IS_CONST) { - if (EXPECTED(CACHED_PTR(opline->extended_value))) { - ce = CACHED_PTR(opline->extended_value); - } else { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } - CACHE_PTR(opline->extended_value, ce); - } - } else if (IS_CONST == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - if (IS_CONST != IS_CONST - && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST - && EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { - value = CACHED_PTR(opline->extended_value + sizeof(void*)); - break; - } - - constant_zv = _get_zval_ptr_tmpvarcv(opline->op2_type, opline->op2, BP_VAR_R EXECUTE_DATA_CC); - if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) { - zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } - constant_name = Z_STR_P(constant_zv); - /* Magic 'class' for constant OP2 is caught at compile-time */ - if ((IS_TMP_VAR|IS_VAR|IS_CV) != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); - FREE_OP(opline->op2_type, opline->op2.var); - ZEND_VM_NEXT_OPCODE(); - } - zv = (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST - ? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name) - : zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name); - - if (EXPECTED(zv != NULL)) { - c = Z_PTR_P(zv); - scope = EX(func)->op_array.scope; - if (!zend_verify_const_access(c, scope)) { - zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } - - if (ce->ce_flags & ZEND_ACC_TRAIT) { - zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } - - bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; - if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) { - if (c->ce->type == ZEND_USER_CLASS) { - /* Recursion protection only applied to user constants, GH-18463 */ - CONST_PROTECT_RECURSION(c); - } - zend_deprecated_class_constant(c, constant_name); - if (c->ce->type == ZEND_USER_CLASS) { - CONST_UNPROTECT_RECURSION(c); - } - - if (EG(exception)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } - } - - value = &c->value; - // Enums require loading of all class constants to build the backed enum table - if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { - if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } - } - if (Z_TYPE_P(value) == IS_CONSTANT_AST) { - if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); - } - } - if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && !is_constant_deprecated) { - CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); - } - } else { - zend_throw_error(NULL, "Undefined constant %s::%s", - ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - FREE_OP(opline->op2_type, opline->op2.var); - HANDLE_EXCEPTION(); + goto mul_double; } - } while (0); - - ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); - - FREE_OP(opline->op2_type, opline->op2.var); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - - op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - - op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - fast_long_sub_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - - op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); + } + + ZEND_VM_DISPATCH_TO_HELPER(zend_mul_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - bool result; + SAVE_OPLINE(); op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + op2 = RT_CONSTANT(opline, opline->op2); + div_function(EX_VAR(opline->result.var), op1, op2); + + + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MOD_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *op1, *op2, *result; op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { + ZEND_VM_TAIL_CALL(zend_mod_by_zero_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) { + /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */ + ZVAL_LONG(result, 0); + } else { + ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2)); + } + ZEND_VM_NEXT_OPCODE(); + } + } + + ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - bool result; op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) + && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { + /* Perform shift on unsigned numbers to get well-defined wrap behavior. */ + ZVAL_LONG(EX_VAR(opline->result.var), + (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2))); + ZEND_VM_NEXT_OPCODE(); + } + + ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SR_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - bool result; op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) + && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } + + ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - bool result; + SAVE_OPLINE(); op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + op2 = RT_CONSTANT(opline, opline->op2); + pow_function(EX_VAR(opline->result.var), op1, op2); + + + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; bool result; + SAVE_OPLINE(); op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); + op2 = RT_CONSTANT(opline, opline->op2); + result = fast_is_identical_function(op1, op2); + + + + + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; bool result; + SAVE_OPLINE(); op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + op2 = RT_CONSTANT(opline, opline->op2); + result = fast_is_not_identical_function(op1, op2); + + + + + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - bool result; + double d1, d2; op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - bool result; + double d1, d2; op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - bool result; + double d1, d2; op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { +is_smaller_true: + ZEND_VM_SMART_BRANCH_TRUE(); + } else { +is_smaller_false: + ZEND_VM_SMART_BRANCH_FALSE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_double: + if (d1 < d2) { + goto is_smaller_true; + } else { + goto is_smaller_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_double; + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - bool result; + double d1, d2; op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { +is_smaller_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { +is_smaller_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_or_equal_double: + if (d1 <= d2) { + goto is_smaller_or_equal_true; + } else { + goto is_smaller_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_or_equal_double; + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container, *dim, *value; - zend_long offset; - HashTable *ht; - - container = RT_CONSTANT(opline, opline->op1); - dim = EX_VAR(opline->op2.var); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_index_array: - if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { - offset = Z_LVAL_P(dim); - } else { - SAVE_OPLINE(); - zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - ht = Z_ARRVAL_P(container); - ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - SAVE_OPLINE(); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_index_array; - } else { - goto fetch_dim_r_index_slow; - } - } else { -fetch_dim_r_index_slow: - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); + zval *op1, *op2; + SAVE_OPLINE(); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = RT_CONSTANT(opline, opline->op2); + compare_function(EX_VAR(opline->result.var), op1, op2); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } -fetch_dim_r_index_undef: - ZVAL_NULL(EX_VAR(opline->result.var)); - SAVE_OPLINE(); - zend_undefined_offset(offset); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_OR_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - SAVE_OPLINE(); op1 = RT_CONSTANT(opline, opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - div_function(EX_VAR(opline->result.var), op1, op2); - + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_DISPATCH_TO_HELPER(zend_bw_or_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_AND_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - SAVE_OPLINE(); op1 = RT_CONSTANT(opline, opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - pow_function(EX_VAR(opline->result.var), op1, op2); - + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_DISPATCH_TO_HELPER(zend_bw_and_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_XOR_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; op1 = RT_CONSTANT(opline, opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); - - if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else if (IS_CONST != IS_CONST && IS_CONST != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { - zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); - } - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_CONST == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2)); ZEND_VM_NEXT_OPCODE(); - } else { - SAVE_OPLINE(); - - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = ZVAL_UNDEFINED_OP1(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = ZVAL_UNDEFINED_OP2(); - } - concat_function(EX_VAR(opline->result.var), op1, op2); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } + + ZEND_VM_DISPATCH_TO_HELPER(zend_bw_xor_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_XOR_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; SAVE_OPLINE(); op1 = RT_CONSTANT(opline, opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - compare_function(EX_VAR(opline->result.var), op1, op2); + op2 = RT_CONSTANT(opline, opline->op2); + boolean_xor_function(EX_VAR(opline->result.var), op1, op2); + + - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container, *dim, *value; SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_CONST & (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 = RT_CONSTANT(opline, opline->op2); if (IS_CONST != IS_CONST) { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R EXECUTE_DATA_CC); + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, 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 (IS_CONST == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { goto fetch_dim_r_array; @@ -65184,35 +59553,39 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_C } } else { fetch_dim_r_slow: - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); } } else { - zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); - zend_fetch_dimension_address_read_IS(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + /* 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, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 USE_OPLINE @@ -65224,14 +59597,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG } ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_CONST == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_CONST & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -65239,11 +59624,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); + if (IS_CONST & (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 (IS_CONST == IS_CONST || (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { do { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + if ((IS_CONST & IS_CV) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; @@ -65252,7 +59641,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - zend_wrong_property_read(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + zend_wrong_property_read(container, RT_CONSTANT(opline, opline->op2)); ZVAL_NULL(EX_VAR(opline->result.var)); goto fetch_obj_r_finish; } while (0); @@ -65264,7 +59653,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH zend_string *name, *tmp_name; zval *retval; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_CONST == IS_CONST) { cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { @@ -65324,7 +59713,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH /* Fall through to read_property for hooks. */ } else if (EXPECTED(zobj->properties != NULL)) { ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); @@ -65357,9 +59746,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH } } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); if (UNEXPECTED(!name)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); break; @@ -65383,7 +59772,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH } #endif - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -65396,13 +59785,14 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH } while (0); fetch_obj_r_finish: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -65410,6 +59800,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ if (IS_CONST == IS_CONST || (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -65420,7 +59812,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH break; } } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { + if (IS_CONST == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); } ZVAL_NULL(EX_VAR(opline->result.var)); @@ -65434,7 +59826,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH zend_string *name, *tmp_name; zval *retval; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_CONST == IS_CONST) { cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { @@ -65461,7 +59853,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH /* Fall through to read_property for hooks. */ } else if (EXPECTED(zobj->properties != NULL)) { ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); @@ -65494,9 +59886,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH } } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); if (UNEXPECTED(!name)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); break; @@ -65505,7 +59897,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -65518,13 +59910,14 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH } while (0); fetch_obj_is_finish: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 USE_OPLINE @@ -65537,23 +59930,36 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH } ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_CONST == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); - zend_fetch_dimension_address_LIST_r(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zend_fetch_dimension_address_LIST_r(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; @@ -65561,16 +59967,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_C op1 = RT_CONSTANT(opline, opline->op1); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { zend_string *op1_str = Z_STR_P(op1); zend_string *op2_str = Z_STR_P(op2); zend_string *str; uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); } else { ZVAL_STR(EX_VAR(opline->result.var), op2_str); @@ -65578,13 +59984,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_C if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op1_str, 0); } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } else if (IS_CONST != IS_CONST && IS_CONST != IS_CV && @@ -65595,7 +60001,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_C memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); GC_ADD_FLAGS(str, flags); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } else { @@ -65607,7 +60013,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_C if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op1_str, 0); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } @@ -65625,12 +60031,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_C } op1_str = zval_get_string_func(op1); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_CONST == IS_CONST) { op2_str = Z_STR_P(op2); } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { op2_str = zend_string_copy(Z_STR_P(op2)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); } op2_str = zval_get_string_func(op2); @@ -65638,7 +60044,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_C do { if (IS_CONST != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_CONST == IS_CONST) { if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { GC_ADDREF(op2_str); } @@ -65648,7 +60054,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_C break; } } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_CONST != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { if (IS_CONST == IS_CONST) { if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { @@ -65669,17 +60075,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_C if (IS_CONST != IS_CONST) { zend_string_release_ex(op1_str, 0); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_CONST != IS_CONST) { zend_string_release_ex(op2_str, 0); } } while (0); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; @@ -65694,19 +60101,19 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ object = RT_CONSTANT(opline, opline->op1); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_CONST != IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && + if (IS_CONST != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); if (UNEXPECTED(EG(exception) != NULL)) { @@ -65715,7 +60122,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ } } zend_throw_error(NULL, "Method name must be a string"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + HANDLE_EXCEPTION(); @@ -65748,17 +60156,19 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { object = ZVAL_UNDEFINED_OP1(); if (UNEXPECTED(EG(exception) != NULL)) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_CONST != IS_CONST) { + + } HANDLE_EXCEPTION(); } } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); } zend_invalid_method_call(object, function_name); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + HANDLE_EXCEPTION(); @@ -65768,29 +60178,30 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ called_scope = obj->ce; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_CONST == IS_CONST && EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); } /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { zend_objects_store_del(orig_obj); } HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_CONST == IS_CONST && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); @@ -65806,8 +60217,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ } } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_CONST != IS_CONST) { + + } call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; @@ -65837,7 +60249,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; @@ -65854,17 +60266,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD if (UNEXPECTED(ce == NULL)) { ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); if (UNEXPECTED(ce == NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_CONST != IS_CONST) { CACHE_PTR(opline->result.num, ce); } } } else if (IS_CONST == IS_UNUSED) { ce = zend_fetch_class(NULL, opline->op1.num); if (UNEXPECTED(ce == NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + HANDLE_EXCEPTION(); } } else { @@ -65872,31 +60286,32 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD } if (IS_CONST == IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && + IS_CONST == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_CONST != IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && + IS_CONST == IS_CONST && EXPECTED(CACHED_PTR(opline->result.num) == ce)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + } else if (IS_CONST != IS_UNUSED) { + function_name = RT_CONSTANT(opline, opline->op2); + if (IS_CONST != IS_CONST) { if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + if (IS_CONST & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } } zend_throw_error(NULL, "Method name must be a string"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + HANDLE_EXCEPTION(); } while (0); } @@ -65905,16 +60320,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_undefined_method(ce, Z_STR_P(function_name)); } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_CONST == IS_CONST && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); @@ -65922,8 +60338,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (IS_CONST != IS_CONST) { + + } } else { if (UNEXPECTED(ce->constructor == NULL)) { @@ -65970,7 +60387,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_USER_CALL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; @@ -65982,7 +60399,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_USER_CALL_SPE uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; SAVE_OPLINE(); - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + function_name = RT_CONSTANT(opline, opline->op2); if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { ZEND_ASSERT(!error); @@ -65990,8 +60407,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_USER_CALL_SPE * invoke a user error handler and throw an exception. * For the CONST and CV case we reuse the same exception block below * to make sure we don't increase VM size too much. */ - if (!((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (!(IS_CONST & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { + + HANDLE_EXCEPTION(); } @@ -66014,8 +60432,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_USER_CALL_SPE call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS; } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { + + if ((IS_CONST & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { if (call_info & ZEND_CALL_CLOSURE) { zend_object_release(ZEND_CLOSURE_OBJECT(func)); } else if (call_info & ZEND_CALL_RELEASE_THIS) { @@ -66030,7 +60448,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_USER_CALL_SPE } else { zend_type_error("%s(): Argument #1 ($callback) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error); efree(error); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + HANDLE_EXCEPTION(); } @@ -66042,7 +60461,217 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_USER_CALL_SPE ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value, *arg; + + if (IS_CONST == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + uint32_t arg_num; + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + + + HANDLE_EXCEPTION(); + } + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + } + + value = RT_CONSTANT(opline, opline->op1); + ZVAL_COPY_VALUE(arg, value); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { + Z_ADDREF_P(arg); + } + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_EX_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value, *arg; + uint32_t arg_num; + + if (IS_CONST == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + + + HANDLE_EXCEPTION(); + } + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + arg_num = opline->op2.num; + } + + if (EXPECTED(arg_num <= MAX_ARG_FLAG_NUM)) { + if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_val_by_ref; + } + } else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { +send_val_by_ref:; + ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg)); + } + value = RT_CONSTANT(opline, opline->op1); + ZVAL_COPY_VALUE(arg, value); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { + Z_ADDREF_P(arg); + } + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zend_class_entry *ce, *scope; + zend_class_constant *c; + zval *value, *zv, *constant_zv; + zend_string *constant_name; + USE_OPLINE + + SAVE_OPLINE(); + + do { + if (IS_CONST == IS_CONST && IS_CONST == IS_CONST) { + if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); + break; + } + } + if (IS_CONST == IS_CONST) { + if (EXPECTED(CACHED_PTR(opline->extended_value))) { + ce = CACHED_PTR(opline->extended_value); + } else { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + + + HANDLE_EXCEPTION(); + } + CACHE_PTR(opline->extended_value, ce); + } + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + + + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + if (IS_CONST != IS_CONST + && IS_CONST == IS_CONST + && EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); + break; + } + + constant_zv = RT_CONSTANT(opline, opline->op2); + if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) { + zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + + + HANDLE_EXCEPTION(); + } + constant_name = Z_STR_P(constant_zv); + /* Magic 'class' for constant OP2 is caught at compile-time */ + if (IS_CONST != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); + + + ZEND_VM_NEXT_OPCODE(); + } + zv = IS_CONST == IS_CONST + ? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name) + : zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name); + + if (EXPECTED(zv != NULL)) { + c = Z_PTR_P(zv); + scope = EX(func)->op_array.scope; + if (!zend_verify_const_access(c, scope)) { + zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + + + HANDLE_EXCEPTION(); + } + + if (ce->ce_flags & ZEND_ACC_TRAIT) { + zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + + + HANDLE_EXCEPTION(); + } + + bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; + if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) { + if (c->ce->type == ZEND_USER_CLASS) { + /* Recursion protection only applied to user constants, GH-18463 */ + CONST_PROTECT_RECURSION(c); + } + zend_deprecated_class_constant(c, constant_name); + if (c->ce->type == ZEND_USER_CLASS) { + CONST_UNPROTECT_RECURSION(c); + } + + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + + + HANDLE_EXCEPTION(); + } + } + + value = &c->value; + // Enums require loading of all class constants to build the backed enum table + if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { + if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + + + HANDLE_EXCEPTION(); + } + } + if (Z_TYPE_P(value) == IS_CONSTANT_AST) { + if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + + + HANDLE_EXCEPTION(); + } + } + if (IS_CONST == IS_CONST && !is_constant_deprecated) { + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); + } + } else { + zend_throw_error(NULL, "Undefined constant %s::%s", + ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + + + HANDLE_EXCEPTION(); + } + } while (0); + + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); + + + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *expr_ptr, new_expr; @@ -66083,15 +60712,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_CONST != IS_UNUSED) { + zval *offset = RT_CONSTANT(opline, opline->op2); zend_string *str; zend_ulong hval; add_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_CONST != IS_CONST) { if (ZEND_HANDLE_NUMERIC(str, hval)) { goto num_index; } @@ -66102,7 +60731,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ hval = Z_LVAL_P(offset); num_index: zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { offset = Z_REFVAL_P(offset); goto add_again; } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { @@ -66135,7 +60764,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ zend_use_resource_as_offset(offset); hval = Z_RES_HANDLE_P(offset); goto num_index; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + } else if (IS_CONST == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); str = ZSTR_EMPTY_ALLOC(); goto str_index; @@ -66143,7 +60772,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ zend_illegal_array_offset_access(offset); zval_ptr_dtor_nogc(expr_ptr); } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + } else { if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { zend_cannot_add_element(); @@ -66153,7 +60783,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *array; uint32_t size; @@ -66168,14 +60798,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CO if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init_mixed(Z_ARRVAL_P(array)); } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { ZVAL_ARR(array, zend_new_array(0)); ZEND_VM_NEXT_OPCODE(); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -66185,7 +60815,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_ SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + offset = RT_CONSTANT(opline, opline->op2); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht; @@ -66197,17 +60827,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_ isset_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_CONST != IS_CONST) { if (ZEND_HANDLE_NUMERIC(str, hval)) { goto num_index_prop; } } - value = zend_hash_find_ex(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST); + value = zend_hash_find_ex(ht, str, IS_CONST == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: value = zend_hash_index_find(ht, hval); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { offset = Z_REFVAL_P(offset); goto isset_again; } else { @@ -66225,1329 +60855,1880 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_ if (IS_CONST & (IS_CONST|IS_CV)) { /* avoid exception check */ - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + + ZEND_VM_SMART_BRANCH(result, 0); + } + } else { + result = (value == NULL || !i_zend_is_true(value)); + } + goto isset_dim_obj_exit; + } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto isset_dim_obj_array; + } + } + + if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; + } + if (!(opline->extended_value & ZEND_ISEMPTY)) { + result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); + } else { + result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); + } + +isset_dim_obj_exit: + + + + + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + int result; + zval *offset; + zend_string *name, *tmp_name; + + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + offset = RT_CONSTANT(opline, opline->op2); + + if (IS_CONST == IS_CONST || + (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } + } else { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } + } + + if (IS_CONST == IS_CONST) { + name = Z_STR_P(offset); + } else { + name = zval_try_get_tmp_string(offset, &tmp_name); + if (UNEXPECTED(!name)) { + result = 0; + goto isset_object_finish; + } + } + + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + +isset_object_finish: + + + + + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *key, *subject; + HashTable *ht; + bool result; + + SAVE_OPLINE(); + + key = RT_CONSTANT(opline, opline->op1); + subject = RT_CONSTANT(opline, opline->op2); + + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: + ht = Z_ARRVAL_P(subject); + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); + } else { + if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } + } + zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); + result = 0; + } + + + + + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zend_class_entry *ce = CACHED_PTR(opline->extended_value); + if (ce == NULL) { + zval *lcname = RT_CONSTANT(opline, opline->op1); + zval *zv = zend_hash_find_known_hash(EG(class_table), Z_STR_P(lcname + 1)); + if (zv) { + SAVE_OPLINE(); + ce = zend_bind_class_in_slot(zv, lcname, Z_STR_P(RT_CONSTANT(opline, opline->op2))); + if (EG(exception)) { + HANDLE_EXCEPTION(); + } + } + CACHE_PTR(opline->extended_value, ce); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_CONST_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *name; + zval *val; + zend_constant c; + + SAVE_OPLINE(); + name = RT_CONSTANT(opline, opline->op1); + val = RT_CONSTANT(opline, opline->op2); + + ZVAL_COPY(&c.value, val); + if (Z_OPT_CONSTANT(c.value)) { + if (UNEXPECTED(zval_update_constant_ex(&c.value, EX(func)->op_array.scope) != SUCCESS)) { + zval_ptr_dtor_nogc(&c.value); + + + + + HANDLE_EXCEPTION(); + } + } + /* non persistent, case sensitive */ + ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT); + c.name = zend_string_copy(Z_STR_P(name)); + + if (zend_register_constant(&c) == NULL) { + } + + + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *name; + zval *val; + zend_constant c, *registered; + + SAVE_OPLINE(); + name = RT_CONSTANT(opline, opline->op1); + val = RT_CONSTANT(opline, opline->op2); + + ZVAL_COPY(&c.value, val); + if (Z_OPT_CONSTANT(c.value)) { + if (UNEXPECTED(zval_update_constant_ex(&c.value, EX(func)->op_array.scope) != SUCCESS)) { + zval_ptr_dtor_nogc(&c.value); + + + + + HANDLE_EXCEPTION(); + } + } + /* non persistent, case sensitive */ + ZEND_CONSTANT_SET_FLAGS(&c, 0, PHP_USER_CONSTANT); + c.name = zend_string_copy(Z_STR_P(name)); + + registered = zend_register_constant(&c); + if (registered == NULL) { + + + + + /* two opcodes used, second one is the data with attributes */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); + } + + HashTable *attributes = Z_PTR_P(get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1)); + ZEND_ASSERT(attributes != NULL); + zend_constant_add_attributes(registered, attributes); + + + + + /* two opcodes used, second one is the data with attributes */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + + SAVE_OPLINE(); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); + + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); + + /* Set the new yielded value */ + if (IS_CONST != IS_UNUSED) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_CONST & (IS_CONST|IS_TMP_VAR)) { + zval *value; + + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + + value = RT_CONSTANT(opline, opline->op1); + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } + } else { + zval *value_ptr = zend_get_bad_ptr(); + + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + do { + if (IS_CONST == IS_VAR) { + ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION + && !Z_ISREF_P(value_ptr)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + ZVAL_COPY(&generator->value, value_ptr); + break; + } + } + if (Z_ISREF_P(value_ptr)) { + Z_ADDREF_P(value_ptr); + } else { + ZVAL_MAKE_REF_EX(value_ptr, 2); + } + ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); + } while (0); + + + } + } else { + zval *value = RT_CONSTANT(opline, opline->op1); + + /* Consts, temporary variables and references need copying */ + if (IS_CONST == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } else if (IS_CONST == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + + + } else { + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CONST == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } + } + } + } else { + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); + } + + /* Set the new yielded key */ + if (IS_CONST != IS_UNUSED) { + zval *key = RT_CONSTANT(opline, opline->op2); + if ((IS_CONST & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + key = Z_REFVAL_P(key); + } + ZVAL_COPY(&generator->key, key); + + + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); + } + } else { + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); + } + + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; + } + + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); + + ZEND_VM_RETURN(); +} + +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SWITCH_LONG_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op, *jump_zv; + HashTable *jumptable; + + op = RT_CONSTANT(opline, opline->op1); + + if (Z_TYPE_P(op) != IS_LONG) { + ZVAL_DEREF(op); + if (Z_TYPE_P(op) != IS_LONG) { + /* Wrong type, fall back to ZEND_CASE chain */ + ZEND_VM_NEXT_OPCODE(); + } + } + + jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); + jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op)); + if (jump_zv != NULL) { + ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); + ZEND_VM_CONTINUE(); + } else { + /* default */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); + } +} + +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SWITCH_STRING_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op, *jump_zv; + HashTable *jumptable; + + op = RT_CONSTANT(opline, opline->op1); + + if (Z_TYPE_P(op) != IS_STRING) { + if (IS_CONST == IS_CONST) { + /* Wrong type, fall back to ZEND_CASE chain */ + ZEND_VM_NEXT_OPCODE(); + } else { + ZVAL_DEREF(op); + if (Z_TYPE_P(op) != IS_STRING) { + /* Wrong type, fall back to ZEND_CASE chain */ + ZEND_VM_NEXT_OPCODE(); + } + } + } + + jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); + jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), IS_CONST == IS_CONST); + if (jump_zv != NULL) { + ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); + ZEND_VM_CONTINUE(); + } else { + /* default */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); + } +} + +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MATCH_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op, *jump_zv; + HashTable *jumptable; + + op = RT_CONSTANT(opline, opline->op1); + jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); + +match_try_again: + if (Z_TYPE_P(op) == IS_LONG) { + jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op)); + } else if (Z_TYPE_P(op) == IS_STRING) { + jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), IS_CONST == IS_CONST); + } else if (Z_TYPE_P(op) == IS_REFERENCE) { + op = Z_REFVAL_P(op); + goto match_try_again; + } else { + if (UNEXPECTED((IS_CONST & IS_CV) && Z_TYPE_P(op) == IS_UNDEF)) { + SAVE_OPLINE(); + op = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + goto match_try_again; + } + + goto default_branch; + } + + if (jump_zv != NULL) { + ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); + ZEND_VM_CONTINUE(); + } else { +default_branch: + /* default */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); + } +} + +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IN_ARRAY_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1; + HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); + zval *result; + + op1 = RT_CONSTANT(opline, opline->op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_CONST == IS_CONST); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + ZEND_VM_SMART_BRANCH(result, 0); + } + + if (opline->extended_value) { + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + result = zend_hash_index_find(ht, Z_LVAL_P(op1)); + ZEND_VM_SMART_BRANCH(result, 0); + } + SAVE_OPLINE(); + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find(ht, Z_STR_P(op1)); + + + ZEND_VM_SMART_BRANCH(result, 0); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + result = zend_hash_index_find(ht, Z_LVAL_P(op1)); + + + ZEND_VM_SMART_BRANCH(result, 0); + } + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + } else if (Z_TYPE_P(op1) <= IS_FALSE) { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + result = zend_hash_find_known_hash(ht, ZSTR_EMPTY_ALLOC()); + ZEND_VM_SMART_BRANCH(result, 0); + } else { + zend_string *key; + zval key_tmp; + + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find(ht, Z_STR_P(op1)); + + ZEND_VM_SMART_BRANCH(result, 0); } - } else { - result = (value == NULL || !i_zend_is_true(value)); - } - goto isset_dim_obj_exit; - } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto isset_dim_obj_array; } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - if (!(opline->extended_value & ZEND_ISEMPTY)) { - result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); - } else { - result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); - } + SAVE_OPLINE(); + ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) { + ZVAL_STR(&key_tmp, key); + if (zend_compare(op1, &key_tmp) == 0) { -isset_dim_obj_exit: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + ZEND_VM_SMART_BRANCH(1, 1); + } + } ZEND_HASH_FOREACH_END(); + } - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_SMART_BRANCH(0, 1); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - int result; - zval *offset; - zend_string *name, *tmp_name; - - SAVE_OPLINE(); - container = RT_CONSTANT(opline, opline->op1); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + zval *op1, *op2, *result; + double d1, d2; - if (IS_CONST == IS_CONST || - (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } - } else { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + fast_long_add_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto add_double; } - } - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(offset); - } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - result = 0; - goto isset_object_finish; + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +add_double: + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, d1 + d2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto add_double; } } - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -isset_object_finish: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *op1, *op2, *result; + double d1, d2; - zval *key, *subject; - HashTable *ht; - bool result; + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + fast_long_sub_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto sub_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +sub_double: + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, d1 - d2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto sub_double; + } + } - SAVE_OPLINE(); + ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} - key = RT_CONSTANT(opline, opline->op1); - subject = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MOD_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { -array_key_exists_array: - ht = Z_ARRVAL_P(subject); - result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); - } else { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { - subject = Z_REFVAL_P(subject); - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { - goto array_key_exists_array; + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { + ZEND_VM_TAIL_CALL(zend_mod_by_zero_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) { + /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */ + ZVAL_LONG(result, 0); + } else { + ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2)); } + ZEND_VM_NEXT_OPCODE(); } - zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); - result = 0; } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CONST_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SL_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *op1, *op2; - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - - SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) + && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { + /* Perform shift on unsigned numbers to get well-defined wrap behavior. */ + ZVAL_LONG(EX_VAR(opline->result.var), + (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2))); + ZEND_VM_NEXT_OPCODE(); } - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); - - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); - - /* Set the new yielded value */ - if (IS_CONST != IS_UNUSED) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_CONST & (IS_CONST|IS_TMP_VAR)) { - zval *value; + ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SR_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; - value = RT_CONSTANT(opline, opline->op1); - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } - } else { - zval *value_ptr = zend_get_bad_ptr(); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) + && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - do { - if (IS_CONST == IS_VAR) { - ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION - && !Z_ISREF_P(value_ptr)) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - ZVAL_COPY(&generator->value, value_ptr); - break; - } - } - if (Z_ISREF_P(value_ptr)) { - Z_ADDREF_P(value_ptr); - } else { - ZVAL_MAKE_REF_EX(value_ptr, 2); - } - ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); - } while (0); + ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { +is_smaller_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { +is_smaller_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); } - } else { - zval *value = RT_CONSTANT(opline, opline->op1); - - /* Consts, temporary variables and references need copying */ - if (IS_CONST == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } else if (IS_CONST == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - - + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_double: + if (d1 < d2) { + goto is_smaller_true; } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CONST == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } + goto is_smaller_false; } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_double; } - } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} - /* Set the new yielded key */ - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *key = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { - key = Z_REFVAL_P(key); - } - ZVAL_COPY(&generator->key, key); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { +is_smaller_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { +is_smaller_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_double: + if (d1 < d2) { + goto is_smaller_true; + } else { + goto is_smaller_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_double; } - } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); - } - - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); - } else { - generator->send_target = NULL; } - - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); - - ZEND_VM_RETURN(); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX int type); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_R_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R)); -} + USE_OPLINE + zval *op1, *op2; + double d1, d2; -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_W_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W)); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { +is_smaller_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + } else { +is_smaller_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_double: + if (d1 < d2) { + goto is_smaller_true; + } else { + goto is_smaller_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_double; + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_RW_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW)); -} + USE_OPLINE + zval *op1, *op2; + double d1, d2; -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - int fetch_type = - (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ? - BP_VAR_W : BP_VAR_R; - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX fetch_type)); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { +is_smaller_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { +is_smaller_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_or_equal_double: + if (d1 <= d2) { + goto is_smaller_or_equal_true; + } else { + goto is_smaller_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_or_equal_double; + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_UNSET_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET)); -} + USE_OPLINE + zval *op1, *op2; + double d1, d2; -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_IS_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS)); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { +is_smaller_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { +is_smaller_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_or_equal_double: + if (d1 <= d2) { + goto is_smaller_or_equal_true; + } else { + goto is_smaller_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_or_equal_double; + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if 0 USE_OPLINE -#endif + zval *op1, *op2; + double d1, d2; - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if (1 && IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { +is_smaller_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { +is_smaller_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_or_equal_double; } - ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - if (IS_UNUSED == IS_UNUSED) { - ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_or_equal_double: + if (d1 <= d2) { + goto is_smaller_or_equal_true; + } else { + goto is_smaller_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_or_equal_double; } - ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zend_class_entry *ce, *scope; + zend_class_constant *c; + zval *value, *zv, *constant_zv; + zend_string *constant_name; USE_OPLINE - zval *function_name; - zend_class_entry *ce; - uint32_t call_info; - zend_function *fbc; - zend_execute_data *call; SAVE_OPLINE(); - if (IS_CONST == IS_CONST) { - /* no function found. try a static method in class */ - ce = CACHED_PTR(opline->result.num); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - - - HANDLE_EXCEPTION(); - } - if (IS_UNUSED != IS_CONST) { - CACHE_PTR(opline->result.num, ce); + do { + if (IS_CONST == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + if (EXPECTED(CACHED_PTR(opline->extended_value + sizeof(void*)))) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); + break; } } - } else if (IS_CONST == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - - - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); - } - - if (IS_CONST == IS_CONST && - IS_UNUSED == IS_CONST && - EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { - /* nothing to do */ - } else if (IS_CONST != IS_CONST && - IS_UNUSED == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == ce)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else if (IS_UNUSED != IS_UNUSED) { - function_name = NULL; - if (IS_UNUSED != IS_CONST) { - if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if (IS_UNUSED & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Method name must be a string"); - - + if (IS_CONST == IS_CONST) { + if (EXPECTED(CACHED_PTR(opline->extended_value))) { + ce = CACHED_PTR(opline->extended_value); + } else { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); HANDLE_EXCEPTION(); - } while (0); + } + CACHE_PTR(opline->extended_value, ce); } - } - - if (ce->get_static_method) { - fbc = ce->get_static_method(ce, Z_STR_P(function_name)); - } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - } - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(ce, Z_STR_P(function_name)); + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); } - - - HANDLE_EXCEPTION(); - } - if (IS_UNUSED == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { - CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); + if (IS_CONST != IS_CONST + && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST + && EXPECTED(CACHED_PTR(opline->extended_value) == ce)) { + value = CACHED_PTR(opline->extended_value + sizeof(void*)); + break; } - if (IS_UNUSED != IS_CONST) { - - } - } else { - if (UNEXPECTED(ce->constructor == NULL)) { - zend_throw_error(NULL, "Cannot call constructor"); - HANDLE_EXCEPTION(); - } - if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { - zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); + constant_zv = _get_zval_ptr_tmpvarcv(opline->op2_type, opline->op2, BP_VAR_R EXECUTE_DATA_CC); + if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) { + zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); HANDLE_EXCEPTION(); } - fbc = ce->constructor; - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); + constant_name = Z_STR_P(constant_zv); + /* Magic 'class' for constant OP2 is caught at compile-time */ + if ((IS_TMP_VAR|IS_VAR|IS_CV) != IS_CONST && UNEXPECTED(zend_string_equals_literal_ci(constant_name, "class"))) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name); + FREE_OP(opline->op2_type, opline->op2.var); + ZEND_VM_NEXT_OPCODE(); } - } + zv = (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST + ? zend_hash_find_known_hash(CE_CONSTANTS_TABLE(ce), constant_name) + : zend_hash_find(CE_CONSTANTS_TABLE(ce), constant_name); - if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { - if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { - ce = (zend_class_entry*)Z_OBJ(EX(This)); - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - } else { - zend_non_static_method_call(fbc); - HANDLE_EXCEPTION(); - } - } else { - /* previous opcode is ZEND_FETCH_CLASS */ - if (IS_CONST == IS_UNUSED - && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || - (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { - if (Z_TYPE(EX(This)) == IS_OBJECT) { - ce = Z_OBJCE(EX(This)); - } else { - ce = Z_CE(EX(This)); + if (EXPECTED(zv != NULL)) { + c = Z_PTR_P(zv); + scope = EX(func)->op_array.scope; + if (!zend_verify_const_access(c, scope)) { + zend_throw_error(NULL, "Cannot access %s constant %s::%s", zend_visibility_string(ZEND_CLASS_CONST_FLAGS(c)), ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); } - } - call_info = ZEND_CALL_NESTED_FUNCTION; - } - - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, ce); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - if (IS_CONST == IS_UNUSED) { - SAVE_OPLINE(); - zend_verify_missing_return_type(EX(func)); - HANDLE_EXCEPTION(); - } else { -/* prevents "undefined variable opline" errors */ -#if 0 || (IS_CONST != IS_UNUSED) - USE_OPLINE - zval *retval_ref, *retval_ptr; - zend_arg_info *ret_info = EX(func)->common.arg_info - 1; - retval_ref = retval_ptr = RT_CONSTANT(opline, opline->op1); - if (IS_CONST == IS_CONST) { - ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr); - retval_ref = retval_ptr = EX_VAR(opline->result.var); - } else if (IS_CONST == IS_VAR) { - if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) { - retval_ref = retval_ptr = Z_INDIRECT_P(retval_ptr); + if (ce->ce_flags & ZEND_ACC_TRAIT) { + zend_throw_error(NULL, "Cannot access trait constant %s::%s directly", ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); } - ZVAL_DEREF(retval_ptr); - } else if (IS_CONST == IS_CV) { - ZVAL_DEREF(retval_ptr); - } - if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { - ZEND_VM_NEXT_OPCODE(); - } + bool is_constant_deprecated = ZEND_CLASS_CONST_FLAGS(c) & ZEND_ACC_DEPRECATED; + if (UNEXPECTED(is_constant_deprecated) && !CONST_IS_RECURSIVE(c)) { + if (c->ce->type == ZEND_USER_CLASS) { + /* Recursion protection only applied to user constants, GH-18463 */ + CONST_PROTECT_RECURSION(c); + } + zend_deprecated_class_constant(c, constant_name); + if (c->ce->type == ZEND_USER_CLASS) { + CONST_UNPROTECT_RECURSION(c); + } - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { - SAVE_OPLINE(); - retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { - ZEND_VM_NEXT_OPCODE(); + if (EG(exception)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } } - } - zend_reference *ref = NULL; - if (UNEXPECTED(retval_ref != retval_ptr)) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - ref = Z_REF_P(retval_ref); - } else { - /* A cast might happen - unwrap the reference if this is a by-value return */ - if (Z_REFCOUNT_P(retval_ref) == 1) { - ZVAL_UNREF(retval_ref); - } else { - Z_DELREF_P(retval_ref); - ZVAL_COPY(retval_ref, retval_ptr); + value = &c->value; + // Enums require loading of all class constants to build the backed enum table + if (ce->ce_flags & ZEND_ACC_ENUM && ce->enum_backing_type != IS_UNDEF && ce->type == ZEND_USER_CLASS && !(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) { + if (UNEXPECTED(zend_update_class_constants(ce) == FAILURE)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); } - retval_ptr = retval_ref; } - } - - SAVE_OPLINE(); - if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, 1, 0))) { - zend_verify_return_error(EX(func), retval_ptr); + if (Z_TYPE_P(value) == IS_CONSTANT_AST) { + if (UNEXPECTED(zend_update_class_constant(c, constant_name, c->ce) != SUCCESS)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); + HANDLE_EXCEPTION(); + } + } + if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && !is_constant_deprecated) { + CACHE_POLYMORPHIC_PTR(opline->extended_value, ce, value); + } + } else { + zend_throw_error(NULL, "Undefined constant %s::%s", + ZSTR_VAL(ce->name), ZSTR_VAL(constant_name)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + FREE_OP(opline->op2_type, opline->op2.var); HANDLE_EXCEPTION(); } - ZEND_VM_NEXT_OPCODE(); -#endif - } -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value, *arg; - - if (IS_UNUSED == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - uint32_t arg_num; - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - + } while (0); - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - } + ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), value); - value = RT_CONSTANT(opline, opline->op1); - ZVAL_COPY_VALUE(arg, value); - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { - Z_ADDREF_P(arg); - } - } + FREE_OP(opline->op2_type, opline->op2.var); ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value, *arg; - uint32_t arg_num; - - if (IS_UNUSED == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - - - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - arg_num = opline->op2.num; - } + zval *op1, *op2, *result; - if (EXPECTED(0)) { - if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - goto send_val_by_ref; - } - } else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { -send_val_by_ref:; - ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg)); - } - value = RT_CONSTANT(opline, opline->op1); - ZVAL_COPY_VALUE(arg, value); - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { - Z_ADDREF_P(arg); - } - } + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2)); ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_QUICK_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value, *arg; - uint32_t arg_num; - - if (IS_UNUSED == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - - - HANDLE_EXCEPTION(); - } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); - arg_num = opline->op2.num; - } + zval *op1, *op2, *result; - if (EXPECTED(1)) { - if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { - goto send_val_by_ref; - } - } else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { -send_val_by_ref:; - ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg)); - } - value = RT_CONSTANT(opline, opline->op1); - ZVAL_COPY_VALUE(arg, value); - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { - Z_ADDREF_P(arg); - } - } + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + fast_long_sub_function(result, op1, op2); ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NEW_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *result; - zend_function *constructor; - zend_class_entry *ce; - zend_execute_data *call; - - SAVE_OPLINE(); - if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - CACHE_PTR(opline->op2.num, ce); - } - } else if (IS_CONST == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op1.num); - if (UNEXPECTED(ce == NULL)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op1.var)); - } + zval *op1, *op2, *result; + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); result = EX_VAR(opline->result.var); - if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { - ZVAL_UNDEF(result); - HANDLE_EXCEPTION(); - } + ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} - constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); - if (constructor == NULL) { - /* If there are no arguments, skip over the DO_FCALL opcode. We check if the next - * opcode is DO_FCALL in case EXT instructions are used. */ - if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) { - ZEND_VM_NEXT_OPCODE_EX(1, 2); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} - /* Perform a dummy function call */ - call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, - opline->extended_value, NULL); - } else { - if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { - init_func_run_time_cache(&constructor->op_array); - } - /* We are not handling overloaded classes right now */ - call = zend_vm_stack_push_call_frame( - ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS, - constructor, - opline->extended_value, - Z_OBJ_P(result)); - Z_ADDREF_P(result); - } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - call->prev_execute_data = EX(call); - EX(call) = call; - ZEND_VM_NEXT_OPCODE(); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *expr_ptr, new_expr; - - SAVE_OPLINE(); - if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && - UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = zend_get_bad_ptr(); - if (Z_ISREF_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } else { - ZVAL_MAKE_REF_EX(expr_ptr, 2); - } + zval *op1, *op2; + bool result; + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} - } else { - expr_ptr = RT_CONSTANT(opline, opline->op1); - if (IS_CONST == IS_TMP_VAR) { - /* pass */ - } else if (IS_CONST == IS_CONST) { - Z_TRY_ADDREF_P(expr_ptr); - } else if (IS_CONST == IS_CV) { - ZVAL_DEREF(expr_ptr); - Z_TRY_ADDREF_P(expr_ptr); - } else /* if (IS_CONST == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(expr_ptr); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - expr_ptr = Z_REFVAL_P(expr_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - ZVAL_COPY_VALUE(&new_expr, expr_ptr); - expr_ptr = &new_expr; - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { - Z_ADDREF_P(expr_ptr); - } - } - } - } + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} - if (IS_UNUSED != IS_UNUSED) { - zval *offset = NULL; - zend_string *str; - zend_ulong hval; +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; -add_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_UNUSED != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index; - } - } -str_index: - zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index: - zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { - offset = Z_REFVAL_P(offset); - goto add_again; - } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { - zval tmp; - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - ZVAL_COPY(&tmp, expr_ptr); - } - zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { - /* A userland error handler can do funky things to the expression, so reset it */ - zval_ptr_dtor(expr_ptr); - ZVAL_COPY_VALUE(expr_ptr, &tmp); - } - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(expr_ptr); - HANDLE_EXCEPTION(); - } - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else if (Z_TYPE_P(offset) == IS_DOUBLE) { - hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); - goto num_index; - } else if (Z_TYPE_P(offset) == IS_FALSE) { - hval = 0; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_TRUE) { - hval = 1; - goto num_index; - } else if (Z_TYPE_P(offset) == IS_RESOURCE) { - zend_use_resource_as_offset(offset); - hval = Z_RES_HANDLE_P(offset); - goto num_index; - } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - str = ZSTR_EMPTY_ALLOC(); - goto str_index; - } else { - zend_illegal_array_offset_access(offset); - zval_ptr_dtor_nogc(expr_ptr); - } + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - } else { - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { - zend_cannot_add_element(); - zval_ptr_dtor_nogc(expr_ptr); - } - } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zval *array; - uint32_t size; USE_OPLINE + zval *op1, *op2; + bool result; - SAVE_OPLINE(); - array = EX_VAR(opline->result.var); - if (IS_CONST != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); - } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZVAL_ARR(array, zend_new_array(0)); - ZEND_VM_NEXT_OPCODE(); - } + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_VAR_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *varname; - zend_string *name, *tmp_name; - HashTable *target_symbol_table; + zval *op1, *op2; + bool result; - SAVE_OPLINE(); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} - varname = RT_CONSTANT(opline, opline->op1); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - if (IS_CONST == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - tmp_name = NULL; - } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = ZVAL_UNDEFINED_OP1(); - } - name = zval_try_get_tmp_string(varname, &tmp_name); - if (UNEXPECTED(!name)) { + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - HANDLE_EXCEPTION(); - } - } + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} - target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); - zend_hash_del_ind(target_symbol_table, name); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - bool result; - zval *varname; - zend_string *name, *tmp_name; - HashTable *target_symbol_table; + zval *container, *dim, *value; + zend_long offset; + HashTable *ht; - SAVE_OPLINE(); - varname = RT_CONSTANT(opline, opline->op1); - if (IS_CONST == IS_CONST) { - name = Z_STR_P(varname); - } else { - name = zval_get_tmp_string(varname, &tmp_name); - } + container = RT_CONSTANT(opline, opline->op1); + dim = EX_VAR(opline->op2.var); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC); - target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); - value = zend_hash_find_ex(target_symbol_table, name, IS_CONST == IS_CONST); - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + ht = Z_ARRVAL_P(container); + ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); - if (!value) { - result = (opline->extended_value & ZEND_ISEMPTY); - } else { - if (Z_TYPE_P(value) == IS_INDIRECT) { - value = Z_INDIRECT_P(value); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); } - if (!(opline->extended_value & ZEND_ISEMPTY)) { - if (Z_ISREF_P(value)) { - value = Z_REFVAL_P(value); - } - result = Z_TYPE_P(value) > IS_NULL; + } else if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; } else { - result = !i_zend_is_true(value); + goto fetch_dim_r_index_slow; + } + } else { +fetch_dim_r_index_slow: + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; } + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - ZEND_VM_SMART_BRANCH(result, true); +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_undefined_offset(offset); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + zval *op1, *op2; SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + div_function(EX_VAR(opline->result.var), op1, op2); - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); - /* Set the new yielded value */ - if (IS_CONST != IS_UNUSED) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_CONST & (IS_CONST|IS_TMP_VAR)) { - zval *value; + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; - value = RT_CONSTANT(opline, opline->op1); - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } - } else { - zval *value_ptr = zend_get_bad_ptr(); + SAVE_OPLINE(); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + pow_function(EX_VAR(opline->result.var), op1, op2); - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - do { - if (IS_CONST == IS_VAR) { - ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION - && !Z_ISREF_P(value_ptr)) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - ZVAL_COPY(&generator->value, value_ptr); - break; - } - } - if (Z_ISREF_P(value_ptr)) { - Z_ADDREF_P(value_ptr); - } else { - ZVAL_MAKE_REF_EX(value_ptr, 2); - } - ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); - } while (0); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - } - } else { - zval *value = RT_CONSTANT(opline, opline->op1); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; - /* Consts, temporary variables and references need copying */ - if (IS_CONST == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } else if (IS_CONST == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CONST == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + } else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else if (IS_CONST != IS_CONST && IS_CONST != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { + zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); } } + ZEND_VM_NEXT_OPCODE(); } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); - } + SAVE_OPLINE(); - /* Set the new yielded key */ - if (IS_UNUSED != IS_UNUSED) { - zval *key = NULL; - if ((IS_UNUSED & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { - key = Z_REFVAL_P(key); + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = ZVAL_UNDEFINED_OP1(); } - ZVAL_COPY(&generator->key, key); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = ZVAL_UNDEFINED_OP2(); + } + concat_function(EX_VAR(opline->result.var), op1, op2); - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); - } - } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +} - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + compare_function(EX_VAR(opline->result.var), op1, op2); + + + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container, *dim, *value; + + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + if (IS_CONST & (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_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_CONST != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_TMP_VAR, BP_VAR_R EXECUTE_DATA_CC); + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } else if (IS_CONST == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; + } + } else { +fetch_dim_r_slow: + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); + } } else { - generator->send_target = NULL; + zend_fetch_dimension_address_read_R(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); - ZEND_VM_RETURN(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MATCH_ERROR_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op; + zval *container; SAVE_OPLINE(); - op = RT_CONSTANT(opline, opline->op1); - zend_match_unhandled_error(op); - HANDLE_EXCEPTION(); + container = RT_CONSTANT(opline, opline->op1); + /* 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_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COUNT_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { +#if 0 USE_OPLINE - zval *op1; - zend_long count; +#endif - SAVE_OPLINE(); - op1 = RT_CONSTANT(opline, opline->op1); + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if (IS_TMP_VAR == IS_UNUSED) { + ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + if (IS_CONST & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } +} - while (1) { - if (Z_TYPE_P(op1) == IS_ARRAY) { - count = zend_hash_num_elements(Z_ARRVAL_P(op1)); - break; - } else if (Z_TYPE_P(op1) == IS_OBJECT) { - zend_object *zobj = Z_OBJ_P(op1); +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + void **cache_slot = NULL; - /* first, we check if the handler is defined */ - if (zobj->handlers->count_elements) { - if (SUCCESS == zobj->handlers->count_elements(zobj, &count)) { - break; - } - if (UNEXPECTED(EG(exception))) { - count = 0; + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + if (IS_CONST & (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 (IS_CONST == IS_CONST || + (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if ((IS_CONST & IS_CV) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; } } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_wrong_property_read(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; + } while (0); + } - /* if not and the object implements Countable we call its count() method */ - if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) { - zval retval; + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; - zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT)); - zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval); - count = zval_get_long(&retval); - zval_ptr_dtor(&retval); - break; - } + if (IS_TMP_VAR == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); - /* If There's no handler and it doesn't implement Countable then emit a TypeError */ - } else if ((IS_CONST & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - continue; - } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - count = 0; - zend_type_error("%s(): Argument #1 ($value) must be of type Countable|array, %s given", opline->extended_value ? "sizeof" : "count", zend_zval_value_name(op1)); - break; - } + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - ZVAL_LONG(EX_VAR(opline->result.var), count); + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_r_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { +fetch_obj_r_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + prop_offset = prop_info->offset; + goto fetch_obj_r_simple; + } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { + zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; + ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); + ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (IS_CONST & IS_CV) { + GC_ADDREF(zobj); + } + if (IS_CONST & (IS_CV|IS_VAR|IS_TMP_VAR)) { + call_info |= ZEND_CALL_RELEASE_THIS; + } + zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); + call->prev_execute_data = execute_data; + call->call = NULL; + call->return_value = EX_VAR(opline->result.var); + call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + execute_data = call; + EG(current_execute_data) = execute_data; + zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GET_CLASS_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE +#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) + opline = hook->op_array.opcodes; +#else + EX(opline) = hook->op_array.opcodes; +#endif + LOAD_OPLINE_EX(); - if (IS_CONST == IS_UNUSED) { - SAVE_OPLINE(); - if (UNEXPECTED(!EX(func)->common.scope)) { - zend_throw_error(NULL, "get_class() without arguments must be called from within a class"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } else { - zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated"); - ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); - } - } else { - zval *op1; - SAVE_OPLINE(); - op1 = RT_CONSTANT(opline, opline->op1); - while (1) { - if (Z_TYPE_P(op1) == IS_OBJECT) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); - } else if ((IS_CONST & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - continue; - } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + + + ZEND_VM_ENTER_EX(); + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } } - zend_type_error("get_class(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(op1)); + } + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + } else { + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; } - break; } +#if ZEND_DEBUG + /* For non-standard object handlers, verify a declared property type in debug builds. + * Fetch prop_info before calling read_property(), as it may deallocate the object. */ + zend_property_info *prop_info = NULL; + if (zobj->handlers->read_property != zend_std_read_property) { + prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); + } +#endif + retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO + && ZEND_TYPE_IS_SET(prop_info->type)) { + ZVAL_OPT_DEREF(retval); + zend_verify_property_type(prop_info, retval, /* strict */ true); + } +#endif - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } -} + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GET_TYPE_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1; - zend_string *type; + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_r_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } + } while (0); - SAVE_OPLINE(); - op1 = RT_CONSTANT(opline, opline->op1); - type = zend_zval_get_legacy_type(op1); - if (EXPECTED(type)) { - ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type); - } else { - ZVAL_STRING(EX_VAR(opline->result.var), "unknown type"); - } +fetch_obj_r_finish: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_array *ht; - uint32_t arg_count, result_size, skip; - - arg_count = EX_NUM_ARGS(); - if (IS_CONST == IS_CONST) { - skip = Z_LVAL_P(RT_CONSTANT(opline, opline->op1)); - if (arg_count < skip) { - result_size = 0; - } else { - result_size = arg_count - skip; - } - } else { - skip = 0; - result_size = arg_count; - } + zval *container; + void **cache_slot = NULL; - if (result_size) { - SAVE_OPLINE(); - uint32_t first_extra_arg = EX(func)->op_array.num_args; + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ - ht = zend_new_array(result_size); - ZVAL_ARR(EX_VAR(opline->result.var), ht); - zend_hash_real_init_packed(ht); - ZEND_HASH_FILL_PACKED(ht) { - zval *p, *q; - uint32_t i = skip; - p = EX_VAR_NUM(i); - if (arg_count > first_extra_arg) { - while (i < first_extra_arg) { - q = p; - if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) { - ZVAL_DEREF(q); - if (Z_OPT_REFCOUNTED_P(q)) { - Z_ADDREF_P(q); - } - ZEND_HASH_FILL_SET(q); - } else { - ZEND_HASH_FILL_SET_NULL(); - } - ZEND_HASH_FILL_NEXT(); - p++; - i++; - } - if (skip < first_extra_arg) { - skip = 0; - } else { - skip -= first_extra_arg; + if (IS_CONST == IS_CONST || + (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; } - p = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T + skip); } - while (i < arg_count) { - q = p; - if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) { - ZVAL_DEREF(q); - if (Z_OPT_REFCOUNTED_P(q)) { - Z_ADDREF_P(q); - } - ZEND_HASH_FILL_SET(q); - } else { - ZEND_HASH_FILL_SET_NULL(); - } - ZEND_HASH_FILL_NEXT(); - p++; - i++; + if (IS_TMP_VAR == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); } - } ZEND_HASH_FILL_END(); - ht->nNumOfElements = result_size; - } else { - ZVAL_EMPTY_ARRAY(EX_VAR(opline->result.var)); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; + } while (0); } - ZEND_VM_NEXT_OPCODE(); -} - -/* Contrary to what its name indicates, ZEND_COPY_TMP may receive and define references. */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - SAVE_OPLINE(); - zend_class_entry *ce = EX(func)->common.scope; - ZEND_ASSERT(ce); + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; - zend_class_entry *parent_ce = ce->parent; - if (!parent_ce) { - zend_throw_error(NULL, "Cannot use \"parent\" when current class scope has no parent"); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } + if (IS_TMP_VAR == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value); - zend_string *property_name = Z_STR_P(RT_CONSTANT(opline, opline->op1)); - zend_property_hook_kind hook_kind = opline->op2.num; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zend_property_info *prop_info = zend_hash_find_ptr(&parent_ce->properties_info, property_name); - if (!prop_info) { - zend_throw_error(NULL, "Undefined property %s::$%s", ZSTR_VAL(parent_ce->name), ZSTR_VAL(property_name)); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - if (prop_info->flags & ZEND_ACC_PRIVATE) { - zend_throw_error(NULL, "Cannot access private property %s::$%s", ZSTR_VAL(parent_ce->name), ZSTR_VAL(property_name)); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_is_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { +fetch_obj_is_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + goto fetch_obj_is_simple; + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); - zend_function **hooks = prop_info->hooks; - zend_function *hook = hooks ? hooks[hook_kind] : NULL; + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); - zend_execute_data *call; - if (hook) { - call = zend_vm_stack_push_call_frame( - ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS, - hook, opline->extended_value, Z_OBJ_P(ZEND_THIS)); - if (EXPECTED(hook->type == ZEND_USER_FUNCTION)) { - if (UNEXPECTED(!RUN_TIME_CACHE(&hook->op_array))) { - init_func_run_time_cache(&hook->op_array); + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } + } + } + } + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + } else { + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; } - call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); } - } else { - zend_function *fbc = zend_get_property_hook_trampoline(prop_info, hook_kind, property_name); - call = zend_vm_stack_push_call_frame( - ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS, - fbc, opline->extended_value, Z_OBJ_P(ZEND_THIS)); - } - - call->prev_execute_data = EX(call); - EX(call) = call; - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; + retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - SAVE_OPLINE(); - op1 = RT_CONSTANT(opline, opline->op1); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - div_function(EX_VAR(opline->result.var), op1, op2); + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_is_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } + } while (0); +fetch_obj_is_finish: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { +#if 0 USE_OPLINE - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = RT_CONSTANT(opline, opline->op1); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - pow_function(EX_VAR(opline->result.var), op1, op2); - +#endif + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + /* Behave like FETCH_OBJ_W */ + if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if (IS_CONST == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + zend_fetch_dimension_address_LIST_r(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; + zend_string *op1_str, *op2_str, *str; - op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { zend_string *op1_str = Z_STR_P(op1); zend_string *op2_str = Z_STR_P(op2); zend_string *str; uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CV == IS_CONST || IS_CV == IS_CV) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); } else { ZVAL_STR(EX_VAR(opline->result.var), op2_str); @@ -67555,27 +62736,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CONST_ if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op1_str, 0); } - } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + } else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } else if (IS_CONST != IS_CONST && IS_CONST != IS_CV && !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { size_t len = ZSTR_LEN(op1_str); - if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { - zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); - } str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); GC_ADD_FLAGS(str, flags); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } else { @@ -67587,732 +62765,928 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CONST_ if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op1_str, 0); } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } ZEND_VM_NEXT_OPCODE(); - } else { - SAVE_OPLINE(); + } + SAVE_OPLINE(); + if (IS_CONST == IS_CONST) { + op1_str = Z_STR_P(op1); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + op1_str = zend_string_copy(Z_STR_P(op1)); + } else { if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = ZVAL_UNDEFINED_OP1(); + ZVAL_UNDEFINED_OP1(); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = ZVAL_UNDEFINED_OP2(); + op1_str = zval_get_string_func(op1); + } + if (IS_TMP_VAR == IS_CONST) { + op2_str = Z_STR_P(op2); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + op2_str = zend_string_copy(Z_STR_P(op2)); + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); } - concat_function(EX_VAR(opline->result.var), op1, op2); - + op2_str = zval_get_string_func(op2); + } + do { + if (IS_CONST != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + zend_string_release_ex(op1_str, 0); + break; + } + } + if (IS_TMP_VAR != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + zend_string_release_ex(op2_str, 0); + break; + } + } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CONST != IS_CONST) { + zend_string_release_ex(op1_str, 0); + } + if (IS_TMP_VAR != IS_CONST) { + zend_string_release_ex(op2_str, 0); + } + } while (0); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *function_name; + zval *object; + zend_function *fbc; + zend_class_entry *called_scope; + zend_object *obj; + zend_execute_data *call; + uint32_t call_info; SAVE_OPLINE(); - op1 = RT_CONSTANT(opline, opline->op1); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - compare_function(EX_VAR(opline->result.var), op1, op2); - + object = RT_CONSTANT(opline, opline->op1); + if (IS_TMP_VAR != IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + if (IS_TMP_VAR != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container, *dim, *value; - SAVE_OPLINE(); - container = RT_CONSTANT(opline, opline->op1); - dim = EX_VAR(opline->op2.var); - if (IS_CONST != IS_CONST) { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R EXECUTE_DATA_CC); - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_array; - } else { - goto fetch_dim_r_slow; - } - } else { -fetch_dim_r_slow: - if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; + HANDLE_EXCEPTION(); + } } - zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); - } - } else { - zend_fetch_dimension_address_read_R(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC); - } + zend_throw_error(NULL, "Method name must be a string"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); + } while (0); + } + if (IS_CONST == IS_UNUSED) { + obj = Z_OBJ_P(object); + } else { + do { + if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + } else { + if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + zend_reference *ref = Z_REF_P(object); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + object = &ref->val; + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + if (IS_CONST & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } + break; + } + } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + object = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_TMP_VAR != IS_CONST) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } + HANDLE_EXCEPTION(); + } + } + if (IS_TMP_VAR == IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + } + zend_invalid_method_call(object, function_name); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - SAVE_OPLINE(); - container = RT_CONSTANT(opline, opline->op1); - zend_fetch_dimension_address_read_IS(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); + HANDLE_EXCEPTION(); + } + } while (0); + } + called_scope = obj->ce; + if (IS_TMP_VAR == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else { + zend_object *orig_obj = obj; + if (IS_TMP_VAR == IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} + /* First, locate the function. */ + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + HANDLE_EXCEPTION(); + } + if (IS_TMP_VAR == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(obj == orig_obj)) { + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); + } + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ -#if 0 - USE_OPLINE -#endif + if (IS_TMP_VAR != IS_CONST) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } } - ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - if (IS_CV == IS_UNUSED) { - ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; + } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { + if (IS_CONST == IS_CV) { + GC_ADDREF(obj); /* For $this pointer */ } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } + + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, obj); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - void **cache_slot = NULL; + zval *function_name; + zend_class_entry *ce; + uint32_t call_info; + zend_function *fbc; + zend_execute_data *call; SAVE_OPLINE(); - container = RT_CONSTANT(opline, opline->op1); - if (IS_CONST == IS_CONST || - (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - break; - } + if (IS_CONST == IS_CONST) { + /* no function found. try a static method in class */ + ce = CACHED_PTR(opline->result.num); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (IS_TMP_VAR != IS_CONST) { + CACHE_PTR(opline->result.num, ce); } - zend_wrong_property_read(container, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_r_finish; - } while (0); + } + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); } - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; - - if (IS_CV == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); - - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_r_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { -fetch_obj_r_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - prop_offset = prop_info->offset; - goto fetch_obj_r_simple; - } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { - zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; - ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); - ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); - - uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (IS_CONST & IS_CV) { - GC_ADDREF(zobj); - } - if (IS_CONST & (IS_CV|IS_VAR|IS_TMP_VAR)) { - call_info |= ZEND_CALL_RELEASE_THIS; - } - zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); - call->prev_execute_data = execute_data; - call->call = NULL; - call->return_value = EX_VAR(opline->result.var); - call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); - - execute_data = call; - EG(current_execute_data) = execute_data; - zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); - -#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) - opline = hook->op_array.opcodes; -#else - EX(opline) = hook->op_array.opcodes; -#endif - LOAD_OPLINE_EX(); - - - - - ZEND_VM_ENTER_EX(); - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); - - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); - - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; - } - } + if (IS_CONST == IS_CONST && + IS_TMP_VAR == IS_CONST && + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { + /* nothing to do */ + } else if (IS_CONST != IS_CONST && + IS_TMP_VAR == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else if (IS_TMP_VAR != IS_UNUSED) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR != IS_CONST) { + if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if (IS_TMP_VAR & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); } } - } + zend_throw_error(NULL, "Method name must be a string"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); + } while (0); } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + } + + if (ce->get_static_method) { + fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + } + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(ce, Z_STR_P(function_name)); } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); + } + if (IS_TMP_VAR == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + if (IS_TMP_VAR != IS_CONST) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } + } else { + if (UNEXPECTED(ce->constructor == NULL)) { + zend_throw_error(NULL, "Cannot call constructor"); + HANDLE_EXCEPTION(); + } + if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { + zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); + HANDLE_EXCEPTION(); + } + fbc = ce->constructor; + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); } + } -#if ZEND_DEBUG - /* For non-standard object handlers, verify a declared property type in debug builds. - * Fetch prop_info before calling read_property(), as it may deallocate the object. */ - zend_property_info *prop_info = NULL; - if (zobj->handlers->read_property != zend_std_read_property) { - prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + } else { + zend_non_static_method_call(fbc); + HANDLE_EXCEPTION(); } -#endif - retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); -#if ZEND_DEBUG - if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { - ZVAL_OPT_DEREF(retval); - zend_verify_property_type(prop_info, retval, /* strict */ true); + } else { + /* previous opcode is ZEND_FETCH_CLASS */ + if (IS_CONST == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { + if (Z_TYPE(EX(This)) == IS_OBJECT) { + ce = Z_OBJCE(EX(This)); + } else { + ce = Z_CE(EX(This)); + } } -#endif + call_info = ZEND_CALL_NESTED_FUNCTION; + } - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_USER_CALL_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + zend_fcall_info_cache fcc; + char *error = NULL; + zend_function *func; + void *object_or_called_scope; + zend_execute_data *call; + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; + + SAVE_OPLINE(); + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { + ZEND_ASSERT(!error); + + /* Deprecation can be emitted from zend_is_callable_ex(), which can + * invoke a user error handler and throw an exception. + * For the CONST and CV case we reuse the same exception block below + * to make sure we don't increase VM size too much. */ + if (!(IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); } - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_r_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); + func = fcc.function_handler; + object_or_called_scope = fcc.called_scope; + if (func->common.fn_flags & ZEND_ACC_CLOSURE) { + /* Delay closure destruction until its invocation */ + GC_ADDREF(ZEND_CLOSURE_OBJECT(func)); + call_info |= ZEND_CALL_CLOSURE; + if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { + call_info |= ZEND_CALL_FAKE_CLOSURE; + } + if (fcc.object) { + object_or_called_scope = fcc.object; + call_info |= ZEND_CALL_HAS_THIS; + } + } else if (fcc.object) { + GC_ADDREF(fcc.object); /* For $this pointer */ + object_or_called_scope = fcc.object; + call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS; } - } while (0); - -fetch_obj_r_finish: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if ((IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { + if (call_info & ZEND_CALL_CLOSURE) { + zend_object_release(ZEND_CLOSURE_OBJECT(func)); + } else if (call_info & ZEND_CALL_RELEASE_THIS) { + zend_object_release(fcc.object); + } + HANDLE_EXCEPTION(); + } + if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&func->op_array))) { + init_func_run_time_cache(&func->op_array); + } + } else { + zend_type_error("%s(): Argument #1 ($callback) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error); + efree(error); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + HANDLE_EXCEPTION(); + } + call = zend_vm_stack_push_call_frame(call_info, + func, opline->extended_value, object_or_called_scope); + call->prev_execute_data = EX(call); + EX(call) = call; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - void **cache_slot = NULL; + zval *expr_ptr, new_expr; SAVE_OPLINE(); - container = RT_CONSTANT(opline, opline->op1); + if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && + UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { + expr_ptr = zend_get_bad_ptr(); + if (Z_ISREF_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } else { + ZVAL_MAKE_REF_EX(expr_ptr, 2); + } - if (IS_CONST == IS_CONST || - (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - break; + + } else { + expr_ptr = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_TMP_VAR) { + /* pass */ + } else if (IS_CONST == IS_CONST) { + Z_TRY_ADDREF_P(expr_ptr); + } else if (IS_CONST == IS_CV) { + ZVAL_DEREF(expr_ptr); + Z_TRY_ADDREF_P(expr_ptr); + } else /* if (IS_CONST == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(expr_ptr); + + expr_ptr = Z_REFVAL_P(expr_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + ZVAL_COPY_VALUE(&new_expr, expr_ptr); + expr_ptr = &new_expr; + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); } } - if (IS_CV == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - } - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_is_finish; - } while (0); + } } - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; - - if (IS_CV == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value); - - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_is_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { -fetch_obj_is_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - goto fetch_obj_is_simple; - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); - - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + if (IS_TMP_VAR != IS_UNUSED) { + zval *offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + zend_string *str; + zend_ulong hval; - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } +add_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_TMP_VAR != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index; } } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; +str_index: + zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index: + zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto add_again; + } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { + zval tmp; + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_COPY(&tmp, expr_ptr); } + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + /* A userland error handler can do funky things to the expression, so reset it */ + zval_ptr_dtor(expr_ptr); + ZVAL_COPY_VALUE(expr_ptr, &tmp); + } + if (UNEXPECTED(EG(exception))) { + zval_ptr_dtor_nogc(expr_ptr); + HANDLE_EXCEPTION(); + } + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + goto num_index; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); + hval = Z_RES_HANDLE_P(offset); + goto num_index; + } else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else { + zend_illegal_array_offset_access(offset); + zval_ptr_dtor_nogc(expr_ptr); } - - retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_is_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } else { + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(expr_ptr); } - } while (0); - -fetch_obj_is_finish: - - - - + } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { -#if 0 + zval *array; + uint32_t size; USE_OPLINE -#endif - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - /* Behave like FETCH_OBJ_W */ - if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + SAVE_OPLINE(); + array = EX_VAR(opline->result.var); + if (IS_CONST != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); } - ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZVAL_ARR(array, zend_new_array(0)); + ZEND_VM_NEXT_OPCODE(); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; + bool result; + zend_ulong hval; + zval *offset; SAVE_OPLINE(); container = RT_CONSTANT(opline, opline->op1); - zend_fetch_dimension_address_LIST_r(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - zend_string *op1_str, *op2_str, *str; - + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - op1 = RT_CONSTANT(opline, opline->op1); - op2 = EX_VAR(opline->op2.var); - if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + zval *value; zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); - if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CV == IS_CONST || IS_CV == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); +isset_dim_obj_array: + ht = Z_ARRVAL_P(container); +isset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_TMP_VAR != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_prop; + } } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); + value = zend_hash_find_ex(ht, str, IS_TMP_VAR == IS_CONST); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_prop: + value = zend_hash_index_find(ht, hval); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + offset = Z_REFVAL_P(offset); + goto isset_again; + } else { + value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); + if (UNEXPECTED(EG(exception))) { + result = 0; + goto isset_dim_obj_exit; } - } else if (IS_CONST != IS_CONST && IS_CONST != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); + } - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); + if (!(opline->extended_value & ZEND_ISEMPTY)) { + /* > IS_NULL means not IS_UNDEF and not IS_NULL */ + result = value != NULL && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + + if (IS_CONST & (IS_CONST|IS_CV)) { + /* avoid exception check */ + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_SMART_BRANCH(result, 0); } } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } + result = (value == NULL || !i_zend_is_true(value)); + } + goto isset_dim_obj_exit; + } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto isset_dim_obj_array; } - ZEND_VM_NEXT_OPCODE(); } - SAVE_OPLINE(); - if (IS_CONST == IS_CONST) { - op1_str = Z_STR_P(op1); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - op1_str = zend_string_copy(Z_STR_P(op1)); - } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - op1_str = zval_get_string_func(op1); + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; } - if (IS_CV == IS_CONST) { - op2_str = Z_STR_P(op2); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - op2_str = zend_string_copy(Z_STR_P(op2)); + if (!(opline->extended_value & ZEND_ISEMPTY)) { + result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - } - op2_str = zval_get_string_func(op2); + result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); } - do { - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { - GC_ADDREF(op2_str); - } - } - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - zend_string_release_ex(op1_str, 0); - break; - } - } - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { - GC_ADDREF(op1_str); - } - } - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - zend_string_release_ex(op2_str, 0); - break; + +isset_dim_obj_exit: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + int result; + zval *offset; + zend_string *name, *tmp_name; + + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + if (IS_CONST == IS_CONST || + (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } + } else { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + } - ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CONST != IS_CONST) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CV != IS_CONST) { - zend_string_release_ex(op2_str, 0); + if (IS_TMP_VAR == IS_CONST) { + name = Z_STR_P(offset); + } else { + name = zval_try_get_tmp_string(offset, &tmp_name); + if (UNEXPECTED(!name)) { + result = 0; + goto isset_object_finish; } - } while (0); + } + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } +isset_object_finish: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zval *object; - zend_function *fbc; - zend_class_entry *called_scope; - zend_object *obj; - zend_execute_data *call; - uint32_t call_info; + + zval *key, *subject; + HashTable *ht; + bool result; SAVE_OPLINE(); - object = RT_CONSTANT(opline, opline->op1); + key = RT_CONSTANT(opline, opline->op1); + subject = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - if (IS_CV != IS_CONST) { - function_name = EX_VAR(opline->op2.var); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: + ht = Z_ARRVAL_P(subject); + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); + } else { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } + } + zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); + result = 0; } - if (IS_CV != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Method name must be a string"); + ZEND_VM_SMART_BRANCH(result, 1); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - HANDLE_EXCEPTION(); - } while (0); + SAVE_OPLINE(); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - if (IS_CONST == IS_UNUSED) { - obj = Z_OBJ_P(object); - } else { - do { - if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - } else { - if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - zend_reference *ref = Z_REF_P(object); + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); - object = &ref->val; - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - if (IS_CONST & IS_VAR) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_ADDREF_P(object); - } - } - break; + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); + + /* Set the new yielded value */ + if (IS_CONST != IS_UNUSED) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_CONST & (IS_CONST|IS_TMP_VAR)) { + zval *value; + + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + + value = RT_CONSTANT(opline, opline->op1); + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); } } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - object = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CV != IS_CONST) { - + } else { + zval *value_ptr = zend_get_bad_ptr(); + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + do { + if (IS_CONST == IS_VAR) { + ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION + && !Z_ISREF_P(value_ptr)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + ZVAL_COPY(&generator->value, value_ptr); + break; } - HANDLE_EXCEPTION(); } - } - if (IS_CV == IS_CONST) { - function_name = EX_VAR(opline->op2.var); - } - zend_invalid_method_call(object, function_name); + if (Z_ISREF_P(value_ptr)) { + Z_ADDREF_P(value_ptr); + } else { + ZVAL_MAKE_REF_EX(value_ptr, 2); + } + ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); + } while (0); + } + } else { + zval *value = RT_CONSTANT(opline, opline->op1); + + /* Consts, temporary variables and references need copying */ + if (IS_CONST == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } else if (IS_CONST == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - HANDLE_EXCEPTION(); + } else { + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CONST == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } } - } while (0); + } + } else { + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); } - called_scope = obj->ce; + /* Set the new yielded key */ + if (IS_TMP_VAR != IS_UNUSED) { + zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + key = Z_REFVAL_P(key); + } + ZVAL_COPY(&generator->key, key); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); + } } else { - zend_object *orig_obj = obj; + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); + } - if (IS_CV == IS_CONST) { - function_name = EX_VAR(opline->op2.var); - } + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; + } - /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); - } + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); + ZEND_VM_RETURN(); +} - if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); - } - HANDLE_EXCEPTION(); - } - if (IS_CV == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); - } - if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ - if (GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); - } - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - } +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX int type); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_R_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R)); +} - if (IS_CV != IS_CONST) { +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_W_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W)); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_RW_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW)); +} - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + int fetch_type = + (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ? + BP_VAR_W : BP_VAR_R; + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX fetch_type)); +} - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { - zend_objects_store_del(obj); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_UNSET_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_IS_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CONST_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS)); +} + +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ +#if 0 + USE_OPLINE +#endif + + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - /* call static method */ - obj = (zend_object*)called_scope; - call_info = ZEND_CALL_NESTED_FUNCTION; - } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { - if (IS_CONST == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if (IS_UNUSED == IS_UNUSED) { + ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; + if (IS_CONST & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, obj); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; @@ -68333,7 +63707,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD HANDLE_EXCEPTION(); } - if (IS_CV != IS_CONST) { + if (IS_UNUSED != IS_CONST) { CACHE_PTR(opline->result.num, ce); } } @@ -68349,24 +63723,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD } if (IS_CONST == IS_CONST && - IS_CV == IS_CONST && + IS_UNUSED == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_CONST != IS_CONST && - IS_CV == IS_CONST && + IS_UNUSED == IS_CONST && EXPECTED(CACHED_PTR(opline->result.num) == ce)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else if (IS_CV != IS_UNUSED) { - function_name = EX_VAR(opline->op2.var); - if (IS_CV != IS_CONST) { + } else if (IS_UNUSED != IS_UNUSED) { + function_name = NULL; + if (IS_UNUSED != IS_CONST) { if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if (IS_CV & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + if (IS_UNUSED & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -68383,7 +63757,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_UNUSED == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { @@ -68393,7 +63767,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD HANDLE_EXCEPTION(); } - if (IS_CV == IS_CONST && + if (IS_UNUSED == IS_CONST && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); @@ -68401,7 +63775,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } - if (IS_CV != IS_CONST) { + if (IS_UNUSED != IS_CONST) { } @@ -68450,81 +63824,248 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_USER_CALL_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zval *function_name; - zend_fcall_info_cache fcc; - char *error = NULL; - zend_function *func; - void *object_or_called_scope; - zend_execute_data *call; - uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; + if (IS_CONST == IS_UNUSED) { + SAVE_OPLINE(); + zend_verify_missing_return_type(EX(func)); + HANDLE_EXCEPTION(); + } else { +/* prevents "undefined variable opline" errors */ +#if 0 || (IS_CONST != IS_UNUSED) + USE_OPLINE + zval *retval_ref, *retval_ptr; + zend_arg_info *ret_info = EX(func)->common.arg_info - 1; + retval_ref = retval_ptr = RT_CONSTANT(opline, opline->op1); - SAVE_OPLINE(); - function_name = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { - ZEND_ASSERT(!error); + if (IS_CONST == IS_CONST) { + ZVAL_COPY(EX_VAR(opline->result.var), retval_ptr); + retval_ref = retval_ptr = EX_VAR(opline->result.var); + } else if (IS_CONST == IS_VAR) { + if (UNEXPECTED(Z_TYPE_P(retval_ptr) == IS_INDIRECT)) { + retval_ref = retval_ptr = Z_INDIRECT_P(retval_ptr); + } + ZVAL_DEREF(retval_ptr); + } else if (IS_CONST == IS_CV) { + ZVAL_DEREF(retval_ptr); + } - /* Deprecation can be emitted from zend_is_callable_ex(), which can - * invoke a user error handler and throw an exception. - * For the CONST and CV case we reuse the same exception block below - * to make sure we don't increase VM size too much. */ - if (!(IS_CV & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { + if (EXPECTED(ZEND_TYPE_CONTAINS_CODE(ret_info->type, Z_TYPE_P(retval_ptr)))) { + ZEND_VM_NEXT_OPCODE(); + } + + if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(retval_ptr))) { + SAVE_OPLINE(); + retval_ref = retval_ptr = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + if (ZEND_TYPE_FULL_MASK(ret_info->type) & MAY_BE_NULL) { + ZEND_VM_NEXT_OPCODE(); + } + } + zend_reference *ref = NULL; + if (UNEXPECTED(retval_ref != retval_ptr)) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + ref = Z_REF_P(retval_ref); + } else { + /* A cast might happen - unwrap the reference if this is a by-value return */ + if (Z_REFCOUNT_P(retval_ref) == 1) { + ZVAL_UNREF(retval_ref); + } else { + Z_DELREF_P(retval_ref); + ZVAL_COPY(retval_ref, retval_ptr); + } + retval_ptr = retval_ref; + } + } + SAVE_OPLINE(); + if (UNEXPECTED(!zend_check_type_slow(&ret_info->type, retval_ptr, ref, 1, 0))) { + zend_verify_return_error(EX(func), retval_ptr); HANDLE_EXCEPTION(); } + ZEND_VM_NEXT_OPCODE(); +#endif + } +} - func = fcc.function_handler; - object_or_called_scope = fcc.called_scope; - if (func->common.fn_flags & ZEND_ACC_CLOSURE) { - /* Delay closure destruction until its invocation */ - GC_ADDREF(ZEND_CLOSURE_OBJECT(func)); - call_info |= ZEND_CALL_CLOSURE; - if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { - call_info |= ZEND_CALL_FAKE_CLOSURE; - } - if (fcc.object) { - object_or_called_scope = fcc.object; - call_info |= ZEND_CALL_HAS_THIS; - } - } else if (fcc.object) { - GC_ADDREF(fcc.object); /* For $this pointer */ - object_or_called_scope = fcc.object; - call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS; +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value, *arg; + + if (IS_UNUSED == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + uint32_t arg_num; + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + + + HANDLE_EXCEPTION(); } + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + } + + value = RT_CONSTANT(opline, opline->op1); + ZVAL_COPY_VALUE(arg, value); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { + Z_ADDREF_P(arg); + } + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value, *arg; + uint32_t arg_num; + + if (IS_UNUSED == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { - if ((IS_CV & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { - if (call_info & ZEND_CALL_CLOSURE) { - zend_object_release(ZEND_CLOSURE_OBJECT(func)); - } else if (call_info & ZEND_CALL_RELEASE_THIS) { - zend_object_release(fcc.object); - } HANDLE_EXCEPTION(); } + } else { + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + arg_num = opline->op2.num; + } - if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&func->op_array))) { - init_func_run_time_cache(&func->op_array); + if (EXPECTED(0)) { + if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_val_by_ref; + } + } else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { +send_val_by_ref:; + ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg)); + } + value = RT_CONSTANT(opline, opline->op1); + ZVAL_COPY_VALUE(arg, value); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { + Z_ADDREF_P(arg); + } + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_EX_SPEC_CONST_UNUSED_QUICK_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value, *arg; + uint32_t arg_num; + + if (IS_UNUSED == IS_CONST) { + SAVE_OPLINE(); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + + + HANDLE_EXCEPTION(); } } else { - zend_type_error("%s(): Argument #1 ($callback) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error); - efree(error); + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + arg_num = opline->op2.num; + } + + if (EXPECTED(1)) { + if (QUICK_ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { + goto send_val_by_ref; + } + } else if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, arg_num)) { +send_val_by_ref:; + ZEND_VM_DISPATCH_TO_HELPER(zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX arg_num, arg)); + } + value = RT_CONSTANT(opline, opline->op1); + ZVAL_COPY_VALUE(arg, value); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { + Z_ADDREF_P(arg); + } + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_NEW_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *result; + zend_function *constructor; + zend_class_entry *ce; + zend_execute_data *call; + SAVE_OPLINE(); + if (IS_CONST == IS_CONST) { + ce = CACHED_PTR(opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + CACHE_PTR(opline->op2.num, ce); + } + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); + } + result = EX_VAR(opline->result.var); + if (UNEXPECTED(object_init_ex(result, ce) != SUCCESS)) { + ZVAL_UNDEF(result); HANDLE_EXCEPTION(); } - call = zend_vm_stack_push_call_frame(call_info, - func, opline->extended_value, object_or_called_scope); + constructor = Z_OBJ_HT_P(result)->get_constructor(Z_OBJ_P(result)); + if (constructor == NULL) { + /* If there are no arguments, skip over the DO_FCALL opcode. We check if the next + * opcode is DO_FCALL in case EXT instructions are used. */ + if (EXPECTED(opline->extended_value == 0 && (opline+1)->opcode == ZEND_DO_FCALL)) { + ZEND_VM_NEXT_OPCODE_EX(1, 2); + } + + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + + /* Perform a dummy function call */ + call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function, + opline->extended_value, NULL); + } else { + if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) { + init_func_run_time_cache(&constructor->op_array); + } + /* We are not handling overloaded classes right now */ + call = zend_vm_stack_push_call_frame( + ZEND_CALL_FUNCTION | ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS, + constructor, + opline->extended_value, + Z_OBJ_P(result)); + Z_ADDREF_P(result); + } + call->prev_execute_data = EX(call); EX(call) = call; - ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *expr_ptr, new_expr; @@ -68565,15 +64106,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ } } - if (IS_CV != IS_UNUSED) { - zval *offset = EX_VAR(opline->op2.var); + if (IS_UNUSED != IS_UNUSED) { + zval *offset = NULL; zend_string *str; zend_ulong hval; add_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); - if (IS_CV != IS_CONST) { + if (IS_UNUSED != IS_CONST) { if (ZEND_HANDLE_NUMERIC(str, hval)) { goto num_index; } @@ -68584,7 +64125,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ hval = Z_LVAL_P(offset); num_index: zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + } else if ((IS_UNUSED & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { offset = Z_REFVAL_P(offset); goto add_again; } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { @@ -68617,7 +64158,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ zend_use_resource_as_offset(offset); hval = Z_RES_HANDLE_P(offset); goto num_index; - } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + } else if (IS_UNUSED == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); str = ZSTR_EMPTY_ALLOC(); goto str_index; @@ -68636,7 +64177,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *array; uint32_t size; @@ -68646,5110 +64187,4116 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CO array = EX_VAR(opline->result.var); if (IS_CONST != IS_UNUSED) { size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); - } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZVAL_ARR(array, zend_new_array(0)); - ZEND_VM_NEXT_OPCODE(); - } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - bool result; - zend_ulong hval; - zval *offset; - - SAVE_OPLINE(); - container = RT_CONSTANT(opline, opline->op1); - offset = EX_VAR(opline->op2.var); - - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; - zval *value; - zend_string *str; - -isset_dim_obj_array: - ht = Z_ARRVAL_P(container); -isset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_CV != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index_prop; - } - } - value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_prop: - value = zend_hash_index_find(ht, hval); - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { - offset = Z_REFVAL_P(offset); - goto isset_again; - } else { - value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); - if (UNEXPECTED(EG(exception))) { - result = 0; - goto isset_dim_obj_exit; - } - } - - if (!(opline->extended_value & ZEND_ISEMPTY)) { - /* > IS_NULL means not IS_UNDEF and not IS_NULL */ - result = value != NULL && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - - if (IS_CONST & (IS_CONST|IS_CV)) { - /* avoid exception check */ - - - ZEND_VM_SMART_BRANCH(result, 0); - } - } else { - result = (value == NULL || !i_zend_is_true(value)); - } - goto isset_dim_obj_exit; - } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto isset_dim_obj_array; - } - } - - if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - if (!(opline->extended_value & ZEND_ISEMPTY)) { - result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); - } else { - result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); - } - -isset_dim_obj_exit: - - - - - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - int result; - zval *offset; - zend_string *name, *tmp_name; - - SAVE_OPLINE(); - container = RT_CONSTANT(opline, opline->op1); - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - - if (IS_CONST == IS_CONST || - (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } - } else { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } - } - - if (IS_CV == IS_CONST) { - name = Z_STR_P(offset); - } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - result = 0; - goto isset_object_finish; - } - } - - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -isset_object_finish: - - - - - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *key, *subject; - HashTable *ht; - bool result; - - SAVE_OPLINE(); - - key = RT_CONSTANT(opline, opline->op1); - subject = EX_VAR(opline->op2.var); - - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { -array_key_exists_array: - ht = Z_ARRVAL_P(subject); - result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); - } else { - if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { - subject = Z_REFVAL_P(subject); - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { - goto array_key_exists_array; - } - } - zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); - result = 0; - } - - - - - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - - SAVE_OPLINE(); - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - - /* Destroy the previously yielded value */ - zval_ptr_dtor(&generator->value); - - /* Destroy the previously yielded key */ - zval_ptr_dtor(&generator->key); - - /* Set the new yielded value */ - if (IS_CONST != IS_UNUSED) { - if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { - /* Constants and temporary variables aren't yieldable by reference, - * but we still allow them with a notice. */ - if (IS_CONST & (IS_CONST|IS_TMP_VAR)) { - zval *value; - - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - - value = RT_CONSTANT(opline, opline->op1); - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } - } else { - zval *value_ptr = zend_get_bad_ptr(); - - /* If a function call result is yielded and the function did - * not return by reference we throw a notice. */ - do { - if (IS_CONST == IS_VAR) { - ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION - && !Z_ISREF_P(value_ptr)) { - zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - ZVAL_COPY(&generator->value, value_ptr); - break; - } - } - if (Z_ISREF_P(value_ptr)) { - Z_ADDREF_P(value_ptr); - } else { - ZVAL_MAKE_REF_EX(value_ptr, 2); - } - ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); - } while (0); - - - } - } else { - zval *value = RT_CONSTANT(opline, opline->op1); - - /* Consts, temporary variables and references need copying */ - if (IS_CONST == IS_CONST) { - ZVAL_COPY_VALUE(&generator->value, value); - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { - Z_ADDREF(generator->value); - } - } else if (IS_CONST == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&generator->value, value); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); - - - } else { - ZVAL_COPY_VALUE(&generator->value, value); - if (IS_CONST == IS_CV) { - if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - } - } - } - } else { - /* If no value was specified yield null */ - ZVAL_NULL(&generator->value); - } - - /* Set the new yielded key */ - if (IS_CV != IS_UNUSED) { - zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - if ((IS_CV & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { - key = Z_REFVAL_P(key); - } - ZVAL_COPY(&generator->key, key); - - - if (Z_TYPE(generator->key) == IS_LONG - && Z_LVAL(generator->key) > generator->largest_used_integer_key - ) { - generator->largest_used_integer_key = Z_LVAL(generator->key); - } - } else { - /* If no key was specified we use auto-increment keys */ - generator->largest_used_integer_key++; - ZVAL_LONG(&generator->key, generator->largest_used_integer_key); - } - - if (RETURN_VALUE_USED(opline)) { - /* If the return value of yield is used set the send - * target and initialize it to NULL */ - generator->send_target = EX_VAR(opline->result.var); - ZVAL_NULL(generator->send_target); - } else { - generator->send_target = NULL; - } - - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); - - ZEND_VM_RETURN(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_NOT_SPEC_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1; - - op1 = EX_VAR(opline->op1.var); - if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), ~Z_LVAL_P(op1)); - ZEND_VM_NEXT_OPCODE(); - } - - ZEND_VM_DISPATCH_TO_HELPER(zend_bw_not_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1)); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - - value = EX_VAR(opline->op1.var); - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(value)); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - - value = EX_VAR(opline->op1.var); - ZVAL_DOUBLE(EX_VAR(opline->result.var), Z_DVAL_P(value)); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - - value = EX_VAR(opline->op1.var); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - double d1, d2; - - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - fast_long_add_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto add_double; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -add_double: - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, d1 + d2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto add_double; - } - } - - ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - double d1, d2; - - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - fast_long_sub_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto sub_double; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -sub_double: - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, d1 - d2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto sub_double; - } - } - - ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - double d1, d2; - - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - zend_long overflow; - - result = EX_VAR(opline->result.var); - ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); - Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto mul_double; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -mul_double: - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, d1 * d2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto mul_double; - } - } - - ZEND_VM_DISPATCH_TO_HELPER(zend_mul_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MOD_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { - ZEND_VM_TAIL_CALL(zend_mod_by_zero_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) { - /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */ - ZVAL_LONG(result, 0); - } else { - ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2)); - } - ZEND_VM_NEXT_OPCODE(); + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_ARR(array, zend_new_array(0)); + ZEND_VM_NEXT_OPCODE(); } - - ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_VAR_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *varname; + zend_string *name, *tmp_name; + HashTable *target_symbol_table; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) - && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { - /* Perform shift on unsigned numbers to get well-defined wrap behavior. */ - ZVAL_LONG(EX_VAR(opline->result.var), - (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2))); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + + varname = RT_CONSTANT(opline, opline->op1); + + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; + } else { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = ZVAL_UNDEFINED_OP1(); + } + name = zval_try_get_tmp_string(varname, &tmp_name); + if (UNEXPECTED(!name)) { + + + HANDLE_EXCEPTION(); + } } - ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); + zend_hash_del_ind(target_symbol_table, name); + + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *value; + bool result; + zval *varname; + zend_string *name, *tmp_name; + HashTable *target_symbol_table; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) - && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + varname = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); } - ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} + target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); + value = zend_hash_find_ex(target_symbol_table, name, IS_CONST == IS_CONST); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { -is_smaller_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - } else { -is_smaller_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_smaller_double; + + if (!value) { + result = (opline->extended_value & ZEND_ISEMPTY); + } else { + if (Z_TYPE_P(value) == IS_INDIRECT) { + value = Z_INDIRECT_P(value); } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_smaller_double: - if (d1 < d2) { - goto is_smaller_true; - } else { - goto is_smaller_false; + if (!(opline->extended_value & ZEND_ISEMPTY)) { + if (Z_ISREF_P(value)) { + value = Z_REFVAL_P(value); } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_smaller_double; + result = Z_TYPE_P(value) > IS_NULL; + } else { + result = !i_zend_is_true(value); } } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + + ZEND_VM_SMART_BRANCH(result, true); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { -is_smaller_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + + SAVE_OPLINE(); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); + + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); + + /* Set the new yielded value */ + if (IS_CONST != IS_UNUSED) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_CONST & (IS_CONST|IS_TMP_VAR)) { + zval *value; + + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + + value = RT_CONSTANT(opline, opline->op1); + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } } else { -is_smaller_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + zval *value_ptr = zend_get_bad_ptr(); + + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + do { + if (IS_CONST == IS_VAR) { + ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION + && !Z_ISREF_P(value_ptr)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + ZVAL_COPY(&generator->value, value_ptr); + break; + } + } + if (Z_ISREF_P(value_ptr)) { + Z_ADDREF_P(value_ptr); + } else { + ZVAL_MAKE_REF_EX(value_ptr, 2); + } + ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); + } while (0); + + } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_smaller_double; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_smaller_double: - if (d1 < d2) { - goto is_smaller_true; + } else { + zval *value = RT_CONSTANT(opline, opline->op1); + + /* Consts, temporary variables and references need copying */ + if (IS_CONST == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } else if (IS_CONST == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); + + } else { - goto is_smaller_false; + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CONST == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_smaller_double; } + } else { + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { -is_smaller_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - } else { -is_smaller_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_smaller_double; + /* Set the new yielded key */ + if (IS_UNUSED != IS_UNUSED) { + zval *key = NULL; + if ((IS_UNUSED & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + key = Z_REFVAL_P(key); } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_smaller_double: - if (d1 < d2) { - goto is_smaller_true; - } else { - goto is_smaller_false; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_smaller_double; + ZVAL_COPY(&generator->key, key); + + + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); } + } else { + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; + } + + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); + + ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MATCH_ERROR_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *op; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { -is_smaller_or_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } else { -is_smaller_or_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - ZVAL_FALSE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_smaller_or_equal_double; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_smaller_or_equal_double: - if (d1 <= d2) { - goto is_smaller_or_equal_true; - } else { - goto is_smaller_or_equal_false; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_smaller_or_equal_double; - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + SAVE_OPLINE(); + op = RT_CONSTANT(opline, opline->op1); + zend_match_unhandled_error(op); + HANDLE_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COUNT_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *op1; + zend_long count; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { -is_smaller_or_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } else { -is_smaller_or_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); - ZVAL_FALSE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + op1 = RT_CONSTANT(opline, opline->op1); + + while (1) { + if (Z_TYPE_P(op1) == IS_ARRAY) { + count = zend_hash_num_elements(Z_ARRVAL_P(op1)); + break; + } else if (Z_TYPE_P(op1) == IS_OBJECT) { + zend_object *zobj = Z_OBJ_P(op1); + + /* first, we check if the handler is defined */ + if (zobj->handlers->count_elements) { + if (SUCCESS == zobj->handlers->count_elements(zobj, &count)) { + break; + } + if (UNEXPECTED(EG(exception))) { + count = 0; + break; + } } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_smaller_or_equal_double; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_smaller_or_equal_double: - if (d1 <= d2) { - goto is_smaller_or_equal_true; - } else { - goto is_smaller_or_equal_false; + + /* if not and the object implements Countable we call its count() method */ + if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) { + zval retval; + + zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT)); + zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval); + count = zval_get_long(&retval); + zval_ptr_dtor(&retval); + break; } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_smaller_or_equal_double; + + /* If There's no handler and it doesn't implement Countable then emit a TypeError */ + } else if ((IS_CONST & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + continue; + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } + count = 0; + zend_type_error("%s(): Argument #1 ($value) must be of type Countable|array, %s given", opline->extended_value ? "sizeof" : "count", zend_zval_value_name(op1)); + break; } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + + ZVAL_LONG(EX_VAR(opline->result.var), count); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GET_CLASS_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { -is_smaller_or_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } else { -is_smaller_or_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); - ZVAL_FALSE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); + if (IS_CONST == IS_UNUSED) { + SAVE_OPLINE(); + if (UNEXPECTED(!EX(func)->common.scope)) { + zend_throw_error(NULL, "get_class() without arguments must be called from within a class"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } else { + zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated"); + ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_smaller_or_equal_double; + ZEND_VM_NEXT_OPCODE(); } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_smaller_or_equal_double: - if (d1 <= d2) { - goto is_smaller_or_equal_true; + } else { + zval *op1; + + SAVE_OPLINE(); + op1 = RT_CONSTANT(opline, opline->op1); + while (1) { + if (Z_TYPE_P(op1) == IS_OBJECT) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); + } else if ((IS_CONST & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + continue; } else { - goto is_smaller_or_equal_false; + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_type_error("get_class(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(op1)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_smaller_or_equal_double; + break; } + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_OR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GET_TYPE_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *op1; + zend_string *type; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + op1 = RT_CONSTANT(opline, opline->op1); + type = zend_zval_get_legacy_type(op1); + if (EXPECTED(type)) { + ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type); + } else { + ZVAL_STRING(EX_VAR(opline->result.var), "unknown type"); } - ZEND_VM_DISPATCH_TO_HELPER(zend_bw_or_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_AND_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zend_array *ht; + uint32_t arg_count, result_size, skip; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); + arg_count = EX_NUM_ARGS(); + if (IS_CONST == IS_CONST) { + skip = Z_LVAL_P(RT_CONSTANT(opline, opline->op1)); + if (arg_count < skip) { + result_size = 0; + } else { + result_size = arg_count - skip; + } + } else { + skip = 0; + result_size = arg_count; } - ZEND_VM_DISPATCH_TO_HELPER(zend_bw_and_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + if (result_size) { + SAVE_OPLINE(); + uint32_t first_extra_arg = EX(func)->op_array.num_args; + + ht = zend_new_array(result_size); + ZVAL_ARR(EX_VAR(opline->result.var), ht); + zend_hash_real_init_packed(ht); + ZEND_HASH_FILL_PACKED(ht) { + zval *p, *q; + uint32_t i = skip; + p = EX_VAR_NUM(i); + if (arg_count > first_extra_arg) { + while (i < first_extra_arg) { + q = p; + if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) { + ZVAL_DEREF(q); + if (Z_OPT_REFCOUNTED_P(q)) { + Z_ADDREF_P(q); + } + ZEND_HASH_FILL_SET(q); + } else { + ZEND_HASH_FILL_SET_NULL(); + } + ZEND_HASH_FILL_NEXT(); + p++; + i++; + } + if (skip < first_extra_arg) { + skip = 0; + } else { + skip -= first_extra_arg; + } + p = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T + skip); + } + while (i < arg_count) { + q = p; + if (EXPECTED(Z_TYPE_INFO_P(q) != IS_UNDEF)) { + ZVAL_DEREF(q); + if (Z_OPT_REFCOUNTED_P(q)) { + Z_ADDREF_P(q); + } + ZEND_HASH_FILL_SET(q); + } else { + ZEND_HASH_FILL_SET_NULL(); + } + ZEND_HASH_FILL_NEXT(); + p++; + i++; + } + } ZEND_HASH_FILL_END(); + ht->nNumOfElements = result_size; + } else { + ZVAL_EMPTY_ARRAY(EX_VAR(opline->result.var)); + } + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_XOR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* Contrary to what its name indicates, ZEND_COPY_TMP may receive and define references. */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + SAVE_OPLINE(); - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); + zend_class_entry *ce = EX(func)->common.scope; + ZEND_ASSERT(ce); + + zend_class_entry *parent_ce = ce->parent; + if (!parent_ce) { + zend_throw_error(NULL, "Cannot use \"parent\" when current class scope has no parent"); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); } - ZEND_VM_DISPATCH_TO_HELPER(zend_bw_xor_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + zend_string *property_name = Z_STR_P(RT_CONSTANT(opline, opline->op1)); + zend_property_hook_kind hook_kind = opline->op2.num; + + zend_property_info *prop_info = zend_hash_find_ptr(&parent_ce->properties_info, property_name); + if (!prop_info) { + zend_throw_error(NULL, "Undefined property %s::$%s", ZSTR_VAL(parent_ce->name), ZSTR_VAL(property_name)); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + if (prop_info->flags & ZEND_ACC_PRIVATE) { + zend_throw_error(NULL, "Cannot access private property %s::$%s", ZSTR_VAL(parent_ce->name), ZSTR_VAL(property_name)); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + + zend_function **hooks = prop_info->hooks; + zend_function *hook = hooks ? hooks[hook_kind] : NULL; + + zend_execute_data *call; + if (hook) { + call = zend_vm_stack_push_call_frame( + ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS, + hook, opline->extended_value, Z_OBJ_P(ZEND_THIS)); + if (EXPECTED(hook->type == ZEND_USER_FUNCTION)) { + if (UNEXPECTED(!RUN_TIME_CACHE(&hook->op_array))) { + init_func_run_time_cache(&hook->op_array); + } + call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); + } + } else { + zend_function *fbc = zend_get_property_hook_trampoline(prop_info, hook_kind, property_name); + call = zend_vm_stack_push_call_frame( + ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS, + fbc, opline->extended_value, Z_OBJ_P(ZEND_THIS)); + } + + call->prev_execute_data = EX(call); + EX(call) = call; + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; + zval *op1, *op2; SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_LIST_r(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + div_function(EX_VAR(opline->result.var), op1, op2); + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op, *jump_zv; - HashTable *jumptable; + zval *op1, *op2; - op = EX_VAR(opline->op1.var); + SAVE_OPLINE(); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + pow_function(EX_VAR(opline->result.var), op1, op2); - if (Z_TYPE_P(op) != IS_LONG) { - ZVAL_DEREF(op); - if (Z_TYPE_P(op) != IS_LONG) { - /* Wrong type, fall back to ZEND_CASE chain */ - ZEND_VM_NEXT_OPCODE(); - } - } - jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); - jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op)); - if (jump_zv != NULL) { - ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); - ZEND_VM_CONTINUE(); - } else { - /* default */ - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op, *jump_zv; - HashTable *jumptable; + zval *op1, *op2; - op = EX_VAR(opline->op1.var); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); - if (Z_TYPE_P(op) != IS_STRING) { - if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* Wrong type, fall back to ZEND_CASE chain */ - ZEND_VM_NEXT_OPCODE(); + if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + + if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else if (IS_CONST != IS_CONST && IS_CONST != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { + zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } } else { - ZVAL_DEREF(op); - if (Z_TYPE_P(op) != IS_STRING) { - /* Wrong type, fall back to ZEND_CASE chain */ - ZEND_VM_NEXT_OPCODE(); + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); } } - } - - jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); - jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST); - if (jump_zv != NULL) { - ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); - ZEND_VM_CONTINUE(); + ZEND_VM_NEXT_OPCODE(); } else { - /* default */ - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } -} + SAVE_OPLINE(); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MATCH_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op, *jump_zv; - HashTable *jumptable; + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = ZVAL_UNDEFINED_OP1(); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = ZVAL_UNDEFINED_OP2(); + } + concat_function(EX_VAR(opline->result.var), op1, op2); - op = EX_VAR(opline->op1.var); - jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); -match_try_again: - if (Z_TYPE_P(op) == IS_LONG) { - jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op)); - } else if (Z_TYPE_P(op) == IS_STRING) { - jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST); - } else if (Z_TYPE_P(op) == IS_REFERENCE) { - op = Z_REFVAL_P(op); - goto match_try_again; - } else { - if (UNEXPECTED(((IS_TMP_VAR|IS_VAR|IS_CV) & IS_CV) && Z_TYPE_P(op) == IS_UNDEF)) { - SAVE_OPLINE(); - op = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - goto match_try_again; - } - goto default_branch; - } - if (jump_zv != NULL) { - ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); - ZEND_VM_CONTINUE(); - } else { -default_branch: - /* default */ - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; + zval *op1, *op2; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = EX_VAR(opline->result.var); - ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} + SAVE_OPLINE(); + op1 = RT_CONSTANT(opline, opline->op1); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + compare_function(EX_VAR(opline->result.var), op1, op2); -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = EX_VAR(opline->result.var); - fast_long_add_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; + zval *container, *dim, *value; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = EX_VAR(opline->result.var); - ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + if (IS_CONST & (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 = EX_VAR(opline->op2.var); + if (IS_CONST != IS_CONST) { + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, BP_VAR_R EXECUTE_DATA_CC); + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } else if (IS_CONST == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; + } + } else { +fetch_dim_r_slow: + if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); + } + } else { + zend_fetch_dimension_address_read_R(container, dim, IS_CV OPLINE_CC EXECUTE_DATA_CC); + } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = EX_VAR(opline->result.var); - fast_long_sub_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; + zval *container; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + /* 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, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); + + + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { +#if 0 USE_OPLINE - zval *op1, *op2, *result; +#endif - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = EX_VAR(opline->result.var); - ZVAL_LONG(result, Z_LVAL_P(op1) * Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if (IS_CV == IS_UNUSED) { + ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + if (IS_CONST & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; - zend_long overflow; + zval *container; + void **cache_slot = NULL; + + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + if (IS_CONST & (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 (IS_CONST == IS_CONST || + (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if ((IS_CONST & IS_CV) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_wrong_property_read(container, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; + } while (0); + } + + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; + + if (IS_CV == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); + + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_r_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { +fetch_obj_r_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + prop_offset = prop_info->offset; + goto fetch_obj_r_simple; + } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { + zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; + ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); + ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = EX_VAR(opline->result.var); - ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); - Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; - ZEND_VM_NEXT_OPCODE(); -} + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (IS_CONST & IS_CV) { + GC_ADDREF(zobj); + } + if (IS_CONST & (IS_CV|IS_VAR|IS_TMP_VAR)) { + call_info |= ZEND_CALL_RELEASE_THIS; + } + zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); + call->prev_execute_data = execute_data; + call->call = NULL; + call->return_value = EX_VAR(opline->result.var); + call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; + execute_data = call; + EG(current_execute_data) = execute_data; + zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} +#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) + opline = hook->op_array.opcodes; +#else + EX(opline) = hook->op_array.opcodes; +#endif + LOAD_OPLINE_EX(); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); -} + ZEND_VM_ENTER_EX(); + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); -} + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } + } + } + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + } else { + name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; + } + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; +#if ZEND_DEBUG + /* For non-standard object handlers, verify a declared property type in debug builds. + * Fetch prop_info before calling read_property(), as it may deallocate the object. */ + zend_property_info *prop_info = NULL; + if (zobj->handlers->read_property != zend_std_read_property) { + prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); + } +#endif + retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO + && ZEND_TYPE_IS_SET(prop_info->type)) { + ZVAL_OPT_DEREF(retval); + zend_verify_property_type(prop_info, retval, /* strict */ true); + } +#endif - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); -} + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_r_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } + } while (0); - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); -} +fetch_obj_r_finish: -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; - - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); -} + zval *container; + void **cache_slot = NULL; -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); -} + if (IS_CONST == IS_CONST || + (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + if (IS_CV == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + } + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; + } while (0); + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); -} + if (IS_CV == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value); -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); -} + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_is_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { +fetch_obj_is_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + goto fetch_obj_is_simple; + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); -} + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || (IS_CONST & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } + } + } + } + name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); + } else { + name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; + } + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1; - bool result; + retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC); - result = Z_TYPE_P(op1) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(op1)) == 0; - FREE_OP(opline->op1_type, opline->op1.var); + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_is_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } + } while (0); - ZEND_VM_SMART_BRANCH_NONE(result, 0); -} +fetch_obj_is_finish: -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1; - bool result; - op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC); - result = Z_TYPE_P(op1) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(op1)) == 0; - FREE_OP(opline->op1_type, opline->op1.var); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { +#if 0 USE_OPLINE - zval *op1; - bool result; - - op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC); - result = Z_TYPE_P(op1) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(op1)) == 0; - FREE_OP(opline->op1_type, opline->op1.var); - +#endif - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + /* Behave like FETCH_OBJ_W */ + if ((IS_CONST & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if (IS_CONST == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1; - bool result; + zval *container; - op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC); - result = Z_TYPE_P(op1) != IS_ARRAY || zend_hash_num_elements(Z_ARR_P(op1)) > 0; - FREE_OP(opline->op1_type, opline->op1.var); + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + zend_fetch_dimension_address_LIST_r(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); - ZEND_VM_SMART_BRANCH_NONE(result, 0); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1; - bool result; - - op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC); - result = Z_TYPE_P(op1) != IS_ARRAY || zend_hash_num_elements(Z_ARR_P(op1)) > 0; - FREE_OP(opline->op1_type, opline->op1.var); + zval *op1, *op2; + zend_string *op1_str, *op2_str, *str; - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); -} + op1 = RT_CONSTANT(opline, opline->op1); + op2 = EX_VAR(opline->op2.var); + if ((IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1; - bool result; + if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else if (IS_CONST != IS_CONST && IS_CONST != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); - op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC); - result = Z_TYPE_P(op1) != IS_ARRAY || zend_hash_num_elements(Z_ARR_P(op1)) > 0; - FREE_OP(opline->op1_type, opline->op1.var); + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } + ZEND_VM_NEXT_OPCODE(); + } + SAVE_OPLINE(); + if (IS_CONST == IS_CONST) { + op1_str = Z_STR_P(op1); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + op1_str = zend_string_copy(Z_STR_P(op1)); + } else { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + op1_str = zval_get_string_func(op1); + } + if (IS_CV == IS_CONST) { + op2_str = Z_STR_P(op2); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + op2_str = zend_string_copy(Z_STR_P(op2)); + } else { + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + } + op2_str = zval_get_string_func(op2); + } + do { + if (IS_CONST != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + zend_string_release_ex(op1_str, 0); + break; + } + } + if (IS_CV != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + zend_string_release_ex(op2_str, 0); + break; + } + } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); -} + ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CONST != IS_CONST) { + zend_string_release_ex(op1_str, 0); + } + if (IS_CV != IS_CONST) { + zend_string_release_ex(op2_str, 0); + } + } while (0); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *function_name; + zval *object; + zend_function *fbc; + zend_class_entry *called_scope; + zend_object *obj; + zend_execute_data *call; + uint32_t call_info; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); -} + SAVE_OPLINE(); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + object = RT_CONSTANT(opline, opline->op1); - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); -} + if (IS_CV != IS_CONST) { + function_name = EX_VAR(opline->op2.var); + } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + if (IS_CV != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Method name must be a string"); - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + HANDLE_EXCEPTION(); + } while (0); + } - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); -} + if (IS_CONST == IS_UNUSED) { + obj = Z_OBJ_P(object); + } else { + do { + if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + } else { + if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + zend_reference *ref = Z_REF_P(object); -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + object = &ref->val; + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + if (IS_CONST & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } + break; + } + } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + object = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_CV != IS_CONST) { - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + } + HANDLE_EXCEPTION(); + } + } + if (IS_CV == IS_CONST) { + function_name = EX_VAR(opline->op2.var); + } + zend_invalid_method_call(object, function_name); - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + HANDLE_EXCEPTION(); + } + } while (0); + } - op1 = EX_VAR(opline->op1.var); - op2 = RT_CONSTANT(opline, opline->op2); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); -} + called_scope = obj->ce; -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - double d1, d2; + if (IS_CV == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else { + zend_object *orig_obj = obj; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - fast_long_add_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto add_double; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -add_double: - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, d1 + d2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto add_double; + if (IS_CV == IS_CONST) { + function_name = EX_VAR(opline->op2.var); } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} + /* First, locate the function. */ + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); + } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - double d1, d2; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - fast_long_sub_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto sub_double; + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + HANDLE_EXCEPTION(); } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -sub_double: - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, d1 - d2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto sub_double; + if (IS_CV == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(obj == orig_obj)) { + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); + } + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); } } - ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} + if (IS_CV != IS_CONST) { -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - double d1, d2; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - zend_long overflow; + } - result = EX_VAR(opline->result.var); - ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); - Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto mul_double; + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { + if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -mul_double: - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, d1 * d2); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto mul_double; + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; + } else if (IS_CONST & (IS_VAR|IS_TMP_VAR|IS_CV)) { + if (IS_CONST == IS_CV) { + GC_ADDREF(obj); /* For $this pointer */ } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } - ZEND_VM_DISPATCH_TO_HELPER(zend_mul_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, obj); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MOD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; + zval *function_name; + zend_class_entry *ce; + uint32_t call_info; + zend_function *fbc; + zend_execute_data *call; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - result = EX_VAR(opline->result.var); - if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { - ZEND_VM_TAIL_CALL(zend_mod_by_zero_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) { - /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */ - ZVAL_LONG(result, 0); - } else { - ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2)); + SAVE_OPLINE(); + + if (IS_CONST == IS_CONST) { + /* no function found. try a static method in class */ + ce = CACHED_PTR(opline->result.num); + if (UNEXPECTED(ce == NULL)) { + ce = zend_fetch_class_by_name(Z_STR_P(RT_CONSTANT(opline, opline->op1)), Z_STR_P(RT_CONSTANT(opline, opline->op1) + 1), ZEND_FETCH_CLASS_DEFAULT | ZEND_FETCH_CLASS_EXCEPTION); + if (UNEXPECTED(ce == NULL)) { + + + HANDLE_EXCEPTION(); + } + if (IS_CV != IS_CONST) { + CACHE_PTR(opline->result.num, ce); } - ZEND_VM_NEXT_OPCODE(); } - } - - ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op1.num); + if (UNEXPECTED(ce == NULL)) { -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) - && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { - /* Perform shift on unsigned numbers to get well-defined wrap behavior. */ - ZVAL_LONG(EX_VAR(opline->result.var), - (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2))); - ZEND_VM_NEXT_OPCODE(); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op1.var)); } - ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} + if (IS_CONST == IS_CONST && + IS_CV == IS_CONST && + EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { + /* nothing to do */ + } else if (IS_CONST != IS_CONST && + IS_CV == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == ce)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else if (IS_CV != IS_UNUSED) { + function_name = EX_VAR(opline->op2.var); + if (IS_CV != IS_CONST) { + if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if (IS_CV & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Method name must be a string"); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) - && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } + HANDLE_EXCEPTION(); + } while (0); + } + } - ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} + if (ce->get_static_method) { + fbc = ce->get_static_method(ce, Z_STR_P(function_name)); + } else { + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + } + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(ce, Z_STR_P(function_name)); + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { -is_smaller_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - } else { -is_smaller_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_smaller_double; + HANDLE_EXCEPTION(); + } + if (IS_CV == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { + CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + if (IS_CV != IS_CONST) { + + + } + } else { + if (UNEXPECTED(ce->constructor == NULL)) { + zend_throw_error(NULL, "Cannot call constructor"); + HANDLE_EXCEPTION(); } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_smaller_double: - if (d1 < d2) { - goto is_smaller_true; - } else { - goto is_smaller_false; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_smaller_double; + if (Z_TYPE(EX(This)) == IS_OBJECT && Z_OBJ(EX(This))->ce != ce->constructor->common.scope && (ce->constructor->common.fn_flags & ZEND_ACC_PRIVATE)) { + zend_throw_error(NULL, "Cannot call private %s::__construct()", ZSTR_VAL(ce->name)); + HANDLE_EXCEPTION(); + } + fbc = ce->constructor; + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); } } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { -is_smaller_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - } else { -is_smaller_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_smaller_double; + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (Z_TYPE(EX(This)) == IS_OBJECT && instanceof_function(Z_OBJCE(EX(This)), ce)) { + ce = (zend_class_entry*)Z_OBJ(EX(This)); + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + } else { + zend_non_static_method_call(fbc); + HANDLE_EXCEPTION(); } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_smaller_double: - if (d1 < d2) { - goto is_smaller_true; + } else { + /* previous opcode is ZEND_FETCH_CLASS */ + if (IS_CONST == IS_UNUSED + && ((opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_PARENT || + (opline->op1.num & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_SELF)) { + if (Z_TYPE(EX(This)) == IS_OBJECT) { + ce = Z_OBJCE(EX(This)); } else { - goto is_smaller_false; + ce = Z_CE(EX(This)); } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_smaller_double; } + call_info = ZEND_CALL_NESTED_FUNCTION; } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, ce); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_USER_CALL_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *function_name; + zend_fcall_info_cache fcc; + char *error = NULL; + zend_function *func; + void *object_or_called_scope; + zend_execute_data *call; + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_DYNAMIC; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { -is_smaller_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - } else { -is_smaller_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_smaller_double; + SAVE_OPLINE(); + function_name = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) { + ZEND_ASSERT(!error); + + /* Deprecation can be emitted from zend_is_callable_ex(), which can + * invoke a user error handler and throw an exception. + * For the CONST and CV case we reuse the same exception block below + * to make sure we don't increase VM size too much. */ + if (!(IS_CV & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { + + + HANDLE_EXCEPTION(); } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_smaller_double: - if (d1 < d2) { - goto is_smaller_true; - } else { - goto is_smaller_false; + + func = fcc.function_handler; + object_or_called_scope = fcc.called_scope; + if (func->common.fn_flags & ZEND_ACC_CLOSURE) { + /* Delay closure destruction until its invocation */ + GC_ADDREF(ZEND_CLOSURE_OBJECT(func)); + call_info |= ZEND_CALL_CLOSURE; + if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { + call_info |= ZEND_CALL_FAKE_CLOSURE; } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_smaller_double; + if (fcc.object) { + object_or_called_scope = fcc.object; + call_info |= ZEND_CALL_HAS_THIS; + } + } else if (fcc.object) { + GC_ADDREF(fcc.object); /* For $this pointer */ + object_or_called_scope = fcc.object; + call_info |= ZEND_CALL_RELEASE_THIS | ZEND_CALL_HAS_THIS; } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { -is_smaller_or_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } else { -is_smaller_or_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - ZVAL_FALSE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); + if ((IS_CV & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) { + if (call_info & ZEND_CALL_CLOSURE) { + zend_object_release(ZEND_CLOSURE_OBJECT(func)); + } else if (call_info & ZEND_CALL_RELEASE_THIS) { + zend_object_release(fcc.object); } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_smaller_or_equal_double; + HANDLE_EXCEPTION(); } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_smaller_or_equal_double: - if (d1 <= d2) { - goto is_smaller_or_equal_true; - } else { - goto is_smaller_or_equal_false; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_smaller_or_equal_double; + + if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&func->op_array))) { + init_func_run_time_cache(&func->op_array); } + } else { + zend_type_error("%s(): Argument #1 ($callback) must be a valid callback, %s", Z_STRVAL_P(RT_CONSTANT(opline, opline->op1)), error); + efree(error); + + + HANDLE_EXCEPTION(); } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + + call = zend_vm_stack_push_call_frame(call_info, + func, opline->extended_value, object_or_called_scope); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *expr_ptr, new_expr; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { -is_smaller_or_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } else { -is_smaller_or_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); - ZVAL_FALSE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_smaller_or_equal_double; + SAVE_OPLINE(); + if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && + UNEXPECTED(opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { + expr_ptr = zend_get_bad_ptr(); + if (Z_ISREF_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } else { + ZVAL_MAKE_REF_EX(expr_ptr, 2); } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_smaller_or_equal_double: - if (d1 <= d2) { - goto is_smaller_or_equal_true; - } else { - goto is_smaller_or_equal_false; + + + } else { + expr_ptr = RT_CONSTANT(opline, opline->op1); + if (IS_CONST == IS_TMP_VAR) { + /* pass */ + } else if (IS_CONST == IS_CONST) { + Z_TRY_ADDREF_P(expr_ptr); + } else if (IS_CONST == IS_CV) { + ZVAL_DEREF(expr_ptr); + Z_TRY_ADDREF_P(expr_ptr); + } else /* if (IS_CONST == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(expr_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(expr_ptr); + + expr_ptr = Z_REFVAL_P(expr_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + ZVAL_COPY_VALUE(&new_expr, expr_ptr); + expr_ptr = &new_expr; + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(expr_ptr)) { + Z_ADDREF_P(expr_ptr); + } } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_smaller_or_equal_double; } } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; + if (IS_CV != IS_UNUSED) { + zval *offset = EX_VAR(opline->op2.var); + zend_string *str; + zend_ulong hval; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { -is_smaller_or_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } else { -is_smaller_or_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); - ZVAL_FALSE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); +add_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_CV != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index; + } } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_smaller_or_equal_double; - } - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_smaller_or_equal_double: - if (d1 <= d2) { - goto is_smaller_or_equal_true; - } else { - goto is_smaller_or_equal_false; +str_index: + zend_hash_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), str, expr_ptr); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index: + zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + offset = Z_REFVAL_P(offset); + goto add_again; + } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { + zval tmp; + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + ZVAL_COPY(&tmp, expr_ptr); } - } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_smaller_or_equal_double; + zend_error(E_DEPRECATED, "Using null as an array offset is deprecated, use an empty string instead"); + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + /* A userland error handler can do funky things to the expression, so reset it */ + zval_ptr_dtor(expr_ptr); + ZVAL_COPY_VALUE(expr_ptr, &tmp); + } + if (UNEXPECTED(EG(exception))) { + zval_ptr_dtor_nogc(expr_ptr); + HANDLE_EXCEPTION(); + } + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else if (Z_TYPE_P(offset) == IS_DOUBLE) { + hval = zend_dval_to_lval_safe(Z_DVAL_P(offset)); + goto num_index; + } else if (Z_TYPE_P(offset) == IS_FALSE) { + hval = 0; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_TRUE) { + hval = 1; + goto num_index; + } else if (Z_TYPE_P(offset) == IS_RESOURCE) { + zend_use_resource_as_offset(offset); + hval = Z_RES_HANDLE_P(offset); + goto num_index; + } else if (IS_CV == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + str = ZSTR_EMPTY_ALLOC(); + goto str_index; + } else { + zend_illegal_array_offset_access(offset); + zval_ptr_dtor_nogc(expr_ptr); + } + + + } else { + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(expr_ptr); } } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + zval *array; + uint32_t size; USE_OPLINE - zval *op1, *op2; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2)); + SAVE_OPLINE(); + array = EX_VAR(opline->result.var); + if (IS_CONST != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_ARR(array, zend_new_array(0)); ZEND_VM_NEXT_OPCODE(); } - - ZEND_VM_DISPATCH_TO_HELPER(zend_bw_or_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_AND_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *container; + bool result; + zend_ulong hval; + zval *offset; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); - } + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + offset = EX_VAR(opline->op2.var); - ZEND_VM_DISPATCH_TO_HELPER(zend_bw_and_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + zval *value; + zend_string *str; -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; +isset_dim_obj_array: + ht = Z_ARRVAL_P(container); +isset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_CV != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_prop; + } + } + value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_prop: + value = zend_hash_index_find(ht, hval); + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + offset = Z_REFVAL_P(offset); + goto isset_again; + } else { + value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); + if (UNEXPECTED(EG(exception))) { + result = 0; + goto isset_dim_obj_exit; + } + } - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) - && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); + if (!(opline->extended_value & ZEND_ISEMPTY)) { + /* > IS_NULL means not IS_UNDEF and not IS_NULL */ + result = value != NULL && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + + if (IS_CONST & (IS_CONST|IS_CV)) { + /* avoid exception check */ + + + ZEND_VM_SMART_BRANCH(result, 0); + } + } else { + result = (value == NULL || !i_zend_is_true(value)); + } + goto isset_dim_obj_exit; + } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto isset_dim_obj_array; + } + } + + if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; + } + if (!(opline->extended_value & ZEND_ISEMPTY)) { + result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); + } else { + result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); } - ZEND_VM_DISPATCH_TO_HELPER(zend_bw_xor_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} +isset_dim_obj_exit: -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - fast_long_add_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} + zval *container; + int result; + zval *offset; + zend_string *name, *tmp_name; -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; + SAVE_OPLINE(); + container = RT_CONSTANT(opline, opline->op1); + offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} + if (IS_CONST == IS_CONST || + (IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } + } else { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } + } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; + if (IS_CV == IS_CONST) { + name = Z_STR_P(offset); + } else { + name = zval_try_get_tmp_string(offset, &tmp_name); + if (UNEXPECTED(!name)) { + result = 0; + goto isset_object_finish; + } + } - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - fast_long_sub_function(result, op1, op2); - ZEND_VM_NEXT_OPCODE(); -} + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} +isset_object_finish: -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_LONG(result, Z_LVAL_P(op1) * Z_LVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2, *result; - zend_long overflow; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); - Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2, *result; - - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = EX_VAR(opline->result.var); - ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2)); - ZEND_VM_NEXT_OPCODE(); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; + zval *key, *subject; + HashTable *ht; bool result; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); -} + SAVE_OPLINE(); -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + key = RT_CONSTANT(opline, opline->op1); + subject = EX_VAR(opline->op2.var); - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); -} + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: + ht = Z_ARRVAL_P(subject); + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); + } else { + if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } + } + zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); + result = 0; + } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); -} + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + SAVE_OPLINE(); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + ZEND_VM_TAIL_CALL(zend_yield_in_closed_generator_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); -} + /* Destroy the previously yielded value */ + zval_ptr_dtor(&generator->value); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + /* Destroy the previously yielded key */ + zval_ptr_dtor(&generator->key); - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); -} + /* Set the new yielded value */ + if (IS_CONST != IS_UNUSED) { + if (UNEXPECTED(EX(func)->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE)) { + /* Constants and temporary variables aren't yieldable by reference, + * but we still allow them with a notice. */ + if (IS_CONST & (IS_CONST|IS_TMP_VAR)) { + zval *value; -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); -} + value = RT_CONSTANT(opline, opline->op1); + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } + } else { + zval *value_ptr = zend_get_bad_ptr(); -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + /* If a function call result is yielded and the function did + * not return by reference we throw a notice. */ + do { + if (IS_CONST == IS_VAR) { + ZEND_ASSERT(value_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION + && !Z_ISREF_P(value_ptr)) { + zend_error(E_NOTICE, "Only variable references should be yielded by reference"); + ZVAL_COPY(&generator->value, value_ptr); + break; + } + } + if (Z_ISREF_P(value_ptr)) { + Z_ADDREF_P(value_ptr); + } else { + ZVAL_MAKE_REF_EX(value_ptr, 2); + } + ZVAL_REF(&generator->value, Z_REF_P(value_ptr)); + } while (0); - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + } + } else { + zval *value = RT_CONSTANT(opline, opline->op1); - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); -} + /* Consts, temporary variables and references need copying */ + if (IS_CONST == IS_CONST) { + ZVAL_COPY_VALUE(&generator->value, value); + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->value))) { + Z_ADDREF(generator->value); + } + } else if (IS_CONST == IS_TMP_VAR) { + ZVAL_COPY_VALUE(&generator->value, value); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + ZVAL_COPY(&generator->value, Z_REFVAL_P(value)); -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); -} + } else { + ZVAL_COPY_VALUE(&generator->value, value); + if (IS_CONST == IS_CV) { + if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); + } + } + } + } else { + /* If no value was specified yield null */ + ZVAL_NULL(&generator->value); + } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + /* Set the new yielded key */ + if (IS_CV != IS_UNUSED) { + zval *key = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + if ((IS_CV & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + key = Z_REFVAL_P(key); + } + ZVAL_COPY(&generator->key, key); - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + if (Z_TYPE(generator->key) == IS_LONG + && Z_LVAL(generator->key) > generator->largest_used_integer_key + ) { + generator->largest_used_integer_key = Z_LVAL(generator->key); + } + } else { + /* If no key was specified we use auto-increment keys */ + generator->largest_used_integer_key++; + ZVAL_LONG(&generator->key, generator->largest_used_integer_key); + } - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); -} + if (RETURN_VALUE_USED(opline)) { + /* If the return value of yield is used set the send + * target and initialize it to NULL */ + generator->send_target = EX_VAR(opline->result.var); + ZVAL_NULL(generator->send_target); + } else { + generator->send_target = NULL; + } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + ZEND_VM_RETURN(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_NOT_SPEC_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *op1; op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), ~Z_LVAL_P(op1)); + ZEND_VM_NEXT_OPCODE(); + } + + ZEND_VM_DISPATCH_TO_HELPER(zend_bw_not_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *value; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); + value = EX_VAR(opline->op1.var); + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(value)); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *value; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + value = EX_VAR(opline->op1.var); + ZVAL_DOUBLE(EX_VAR(opline->result.var), Z_DVAL_P(value)); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *value; - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); + value = EX_VAR(opline->op1.var); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *op1, *op2, *result; + double d1, d2; op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + fast_long_add_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto add_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +add_double: + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, d1 + d2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto add_double; + } + } + + ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *op1, *op2, *result; + double d1, d2; op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + fast_long_sub_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto sub_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +sub_double: + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, d1 - d2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto sub_double; + } + } + + ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *op1, *op2, *result; + double d1, d2; op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); -} + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + zend_long overflow; -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; + result = EX_VAR(opline->result.var); + ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); + Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto mul_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +mul_double: + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, d1 * d2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto mul_double; + } + } - op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_NONE(result, 0); + ZEND_VM_DISPATCH_TO_HELPER(zend_mul_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MOD_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - bool result; + zval *op1, *op2, *result; op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPZ(result, 0); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { + ZEND_VM_TAIL_CALL(zend_mod_by_zero_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) { + /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */ + ZVAL_LONG(result, 0); + } else { + ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2)); + } + ZEND_VM_NEXT_OPCODE(); + } + } + + ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - bool result; op1 = EX_VAR(opline->op1.var); - op2 = EX_VAR(opline->op2.var); - result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); - ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_LIST_r(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op; + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) + && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { + /* Perform shift on unsigned numbers to get well-defined wrap behavior. */ + ZVAL_LONG(EX_VAR(opline->result.var), + (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2))); + ZEND_VM_NEXT_OPCODE(); + } - SAVE_OPLINE(); - op = EX_VAR(opline->op1.var); - zend_match_unhandled_error(op); - HANDLE_EXCEPTION(); + ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - - SAVE_OPLINE(); - container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_LIST_r(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); + zval *op1, *op2; + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) + && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_NOT_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; + zval *op1, *op2; + double d1, d2; - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - /* The result and op1 can be the same cv zval */ - const uint32_t orig_val_type = Z_TYPE_INFO_P(val); - ZVAL_TRUE(EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { +is_smaller_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { +is_smaller_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_double: + if (d1 < d2) { + goto is_smaller_true; + } else { + goto is_smaller_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_double; } - } else { - SAVE_OPLINE(); - ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ECHO_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *z; - - SAVE_OPLINE(); - z = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (Z_TYPE_P(z) == IS_STRING) { - zend_string *str = Z_STR_P(z); + zval *op1, *op2; + double d1, d2; - if (ZSTR_LEN(str) != 0) { - zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { +is_smaller_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { +is_smaller_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_double; } - } else { - zend_string *str = zval_get_string_func(z); - - if (ZSTR_LEN(str) != 0) { - zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_double: + if (d1 < d2) { + goto is_smaller_true; + } else { + goto is_smaller_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_double; } - zend_string_release_ex(str, 0); } - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPZ_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; - uint8_t op1_type; - - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zval *op1, *op2; + double d1, d2; - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { +is_smaller_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + } else { +is_smaller_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_double; } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - - SAVE_OPLINE(); - op1_type = (IS_TMP_VAR|IS_VAR); - if (i_zend_is_true(val)) { - opline++; - } else { - opline = OP_JMP_ADDR(opline, opline->op2); - } - if (op1_type & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_nogc(val); - } - ZEND_VM_JMP(opline); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPNZ_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val; - uint8_t op1_type; - - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_double: + if (d1 < d2) { + goto is_smaller_true; + } else { + goto is_smaller_false; } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_double; } - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - op1_type = (IS_TMP_VAR|IS_VAR); - if (i_zend_is_true(val)) { - opline = OP_JMP_ADDR(opline, opline->op2); - } else { - opline++; - } - if (op1_type & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_nogc(val); } - ZEND_VM_JMP(opline); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPZ_EX_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; - bool ret; - - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zval *op1, *op2; + double d1, d2; - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_NEXT_OPCODE(); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { +is_smaller_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { +is_smaller_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_or_equal_double: + if (d1 <= d2) { + goto is_smaller_or_equal_true; + } else { + goto is_smaller_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_or_equal_double; } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - - SAVE_OPLINE(); - ret = i_zend_is_true(val); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - if (ret) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - opline++; - } else { - ZVAL_FALSE(EX_VAR(opline->result.var)); - opline = OP_JMP_ADDR(opline, opline->op2); } - ZEND_VM_JMP(opline); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPNZ_EX_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; - bool ret; - - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zval *op1, *op2; + double d1, d2; - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_NEXT_OPCODE(); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { +is_smaller_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { +is_smaller_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_or_equal_double: + if (d1 <= d2) { + goto is_smaller_or_equal_true; + } else { + goto is_smaller_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_or_equal_double; } } - - SAVE_OPLINE(); - ret = i_zend_is_true(val); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - if (ret) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - opline = OP_JMP_ADDR(opline, opline->op2); - } else { - ZVAL_FALSE(EX_VAR(opline->result.var)); - opline++; - } - ZEND_VM_JMP(opline); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FREE_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - SAVE_OPLINE(); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_FREE_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zval *var; USE_OPLINE + zval *op1, *op2; + double d1, d2; - var = EX_VAR(opline->op1.var); - if (Z_TYPE_P(var) != IS_ARRAY) { - SAVE_OPLINE(); - if (Z_FE_ITER_P(var) != (uint32_t)-1) { - zend_hash_iterator_del(Z_FE_ITER_P(var)); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { +is_smaller_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { +is_smaller_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_or_equal_double: + if (d1 <= d2) { + goto is_smaller_or_equal_true; + } else { + goto is_smaller_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_or_equal_double; } - zval_ptr_dtor_nogc(var); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - - /* This is freeing an array. Use an inlined version of zval_ptr_dtor_nogc. */ - /* PHP only needs to save the opline and check for an exception if the last reference to the array was garbage collected (destructors of elements in the array could throw an exception) */ - if (Z_REFCOUNTED_P(var) && !Z_DELREF_P(var)) { - SAVE_OPLINE(); - rc_dtor_func(Z_COUNTED_P(var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_THROW_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_OR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zval *op1, *op2; - do { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - value = Z_REFVAL_P(value); - if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { - break; - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Can only throw objects"); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } while (0); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } - zend_exception_save(); - Z_TRY_ADDREF_P(value); - zend_throw_exception_object(value); - zend_exception_restore(); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); + ZEND_VM_DISPATCH_TO_HELPER(zend_bw_or_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_AND_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val; + zval *op1, *op2; - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (Z_TYPE_INFO_P(val) == IS_TRUE) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { - /* The result and op1 can be the same cv zval */ - const uint32_t orig_val_type = Z_TYPE_INFO_P(val); - ZVAL_FALSE(EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - } else { - SAVE_OPLINE(); - ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); } - ZEND_VM_NEXT_OPCODE(); + + ZEND_VM_DISPATCH_TO_HELPER(zend_bw_and_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CLONE_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_XOR_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *obj; - zend_object *zobj; - zend_class_entry *ce, *scope; - zend_function *clone; - zend_object_clone_obj_t clone_call; - - SAVE_OPLINE(); - obj = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. - * The OPcode intentionally does not support a clone-with property list to keep it simple. */ - - do { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) { - obj = Z_REFVAL_P(obj); - if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) { - break; - } - } - ZVAL_UNDEF(EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } while (0); - - zobj = Z_OBJ_P(obj); - ce = zobj->ce; - clone = ce->clone; - clone_call = zobj->handlers->clone_obj; - if (UNEXPECTED(clone_call == NULL)) { - zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } + zval *op1, *op2; - if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) { - scope = EX(func)->op_array.scope; - ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC)); - if (!zend_check_method_accessible(clone, scope)) { - zend_bad_method_call(clone, clone->common.function_name, scope); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); } - ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj)); - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_DISPATCH_TO_HELPER(zend_bw_xor_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_op_array *new_op_array; - zval *inc_filename; + zval *container; SAVE_OPLINE(); - inc_filename = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - new_op_array = zend_include_or_eval(inc_filename, opline->extended_value); - if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) { - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); - } - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else if (new_op_array == ZEND_FAKE_OP_ARRAY) { - if (RETURN_VALUE_USED(opline)) { - ZVAL_TRUE(EX_VAR(opline->result.var)); - } - } else if (UNEXPECTED(new_op_array == NULL)) { - if (RETURN_VALUE_USED(opline)) { - ZVAL_FALSE(EX_VAR(opline->result.var)); - } - } else if (new_op_array->last == 1 - && new_op_array->opcodes[0].opcode == ZEND_RETURN - && new_op_array->opcodes[0].op1_type == IS_CONST - && EXPECTED(zend_execute_ex == execute_ex)) { - if (RETURN_VALUE_USED(opline)) { - const zend_op *op = new_op_array->opcodes; - - ZVAL_COPY(EX_VAR(opline->result.var), RT_CONSTANT(op, op->op1)); - } - zend_destroy_static_vars(new_op_array); - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); - } else { - zval *return_value = NULL; - zend_execute_data *call; - if (RETURN_VALUE_USED(opline)) { - return_value = EX_VAR(opline->result.var); - } - - new_op_array->scope = EX(func)->op_array.scope; + container = EX_VAR(opline->op1.var); + zend_fetch_dimension_address_LIST_r(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); - call = zend_vm_stack_push_call_frame( - (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, - (zend_function*)new_op_array, 0, - Z_PTR(EX(This))); - if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { - call->symbol_table = EX(symbol_table); - } else { - call->symbol_table = zend_rebuild_symbol_table(); - } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - call->prev_execute_data = execute_data; - i_init_code_execute_data(call, new_op_array, return_value); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op, *jump_zv; + HashTable *jumptable; + op = EX_VAR(opline->op1.var); - if (EXPECTED(zend_execute_ex == execute_ex)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_ENTER(); - } else { - ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); - zend_execute_ex(call); - zend_vm_stack_free_call_frame(call); + if (Z_TYPE_P(op) != IS_LONG) { + ZVAL_DEREF(op); + if (Z_TYPE_P(op) != IS_LONG) { + /* Wrong type, fall back to ZEND_CASE chain */ + ZEND_VM_NEXT_OPCODE(); } + } - zend_destroy_static_vars(new_op_array); - destroy_op_array(new_op_array); - efree_size(new_op_array, sizeof(zend_op_array)); - if (UNEXPECTED(EG(exception) != NULL)) { - zend_rethrow_exception(execute_data); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } + jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); + jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op)); + if (jump_zv != NULL) { + ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); + ZEND_VM_CONTINUE(); + } else { + /* default */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_FROM_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - zval *val; - - SAVE_OPLINE(); - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { - zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator"); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - -yield_from_try_again: - if (Z_TYPE_P(val) == IS_ARRAY) { - ZVAL_COPY_VALUE(&generator->values, val); - if (Z_OPT_REFCOUNTED_P(val)) { - Z_ADDREF_P(val); - } - Z_FE_POS(generator->values) = 0; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) { - zend_class_entry *ce = Z_OBJCE_P(val); - if (ce == zend_ce_generator) { - zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); + zval *op, *jump_zv; + HashTable *jumptable; - Z_ADDREF_P(val); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + op = EX_VAR(opline->op1.var); - if (UNEXPECTED(new_gen->execute_data == NULL)) { - zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); - zval_ptr_dtor(val); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else if (Z_ISUNDEF(new_gen->retval)) { - if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) { - zend_throw_error(NULL, "Impossible to yield from the Generator being currently run"); - zval_ptr_dtor(val); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } else { - zend_generator_yield_from(generator, new_gen); - } - } else { - if (RETURN_VALUE_USED(opline)) { - ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval); - } - ZEND_VM_NEXT_OPCODE(); - } + if (Z_TYPE_P(op) != IS_STRING) { + if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* Wrong type, fall back to ZEND_CASE chain */ + ZEND_VM_NEXT_OPCODE(); } else { - zend_object_iterator *iter = ce->get_iterator(ce, val, 0); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) { - if (!EG(exception)) { - zend_throw_error(NULL, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name)); - } - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } - - iter->index = 0; - if (iter->funcs->rewind) { - iter->funcs->rewind(iter); - if (UNEXPECTED(EG(exception) != NULL)) { - OBJ_RELEASE(&iter->std); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); - } + ZVAL_DEREF(op); + if (Z_TYPE_P(op) != IS_STRING) { + /* Wrong type, fall back to ZEND_CASE chain */ + ZEND_VM_NEXT_OPCODE(); } - - ZVAL_OBJ(&generator->values, &iter->std); } - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(val) == IS_REFERENCE) { - val = Z_REFVAL_P(val); - goto yield_from_try_again; - } else { - zend_throw_error(NULL, "Can use \"yield from\" only with arrays and Traversables"); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - UNDEF_RESULT(); - HANDLE_EXCEPTION(); } - /* This is the default return value - * when the expression is a Generator, it will be overwritten in zend_generator_resume() */ - if (RETURN_VALUE_USED(opline)) { - ZVAL_NULL(EX_VAR(opline->result.var)); + jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); + jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST); + if (jump_zv != NULL) { + ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); + ZEND_VM_CONTINUE(); + } else { + /* default */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } - - /* This generator has no send target (though the generator we delegate to might have one) */ - generator->send_target = NULL; - - /* The GOTO VM uses a local opline variable. We need to set the opline - * variable in execute_data so we don't resume at an old position. */ - SAVE_OPLINE(); - - ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_STRLEN_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MATCH_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; + zval *op, *jump_zv; + HashTable *jumptable; - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(value); - } - ZEND_VM_NEXT_OPCODE(); - } else { - bool strict; + op = EX_VAR(opline->op1.var); + jumptable = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) { - value = Z_REFVAL_P(value); - if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { - ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); +match_try_again: + if (Z_TYPE_P(op) == IS_LONG) { + jump_zv = zend_hash_index_find(jumptable, Z_LVAL_P(op)); + } else if (Z_TYPE_P(op) == IS_STRING) { + jump_zv = zend_hash_find_ex(jumptable, Z_STR_P(op), (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST); + } else if (Z_TYPE_P(op) == IS_REFERENCE) { + op = Z_REFVAL_P(op); + goto match_try_again; + } else { + if (UNEXPECTED(((IS_TMP_VAR|IS_VAR|IS_CV) & IS_CV) && Z_TYPE_P(op) == IS_UNDEF)) { + SAVE_OPLINE(); + op = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); } + goto match_try_again; } - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - value = ZVAL_UNDEFINED_OP1(); - } - strict = EX_USES_STRICT_TYPES(); - do { - if (EXPECTED(!strict)) { - zend_string *str; - zval tmp; - - if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) { - zend_error(E_DEPRECATED, - "strlen(): Passing null to parameter #1 ($string) of type string is deprecated"); - ZVAL_LONG(EX_VAR(opline->result.var), 0); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - break; - } + goto default_branch; + } - ZVAL_COPY(&tmp, value); - if (zend_parse_arg_str_weak(&tmp, &str, 1)) { - ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str)); - zval_ptr_dtor(&tmp); - break; - } - zval_ptr_dtor(&tmp); - } - if (!EG(exception)) { - zend_type_error("strlen(): Argument #1 ($string) must be of type string, %s given", zend_zval_value_name(value)); - } - ZVAL_UNDEF(EX_VAR(opline->result.var)); - } while (0); + if (jump_zv != NULL) { + ZEND_VM_SET_RELATIVE_OPCODE(opline, Z_LVAL_P(jump_zv)); + ZEND_VM_CONTINUE(); + } else { +default_branch: + /* default */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_TYPE_CHECK_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - int result = 0; + zval *op1, *op2, *result; - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { -type_check_resource: - if (opline->extended_value != MAY_BE_RESOURCE - || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) { - result = 1; - } - } else if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) { - value = Z_REFVAL_P(value); - if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { - goto type_check_resource; - } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - result = ((1 << IS_NULL) & opline->extended_value) != 0; - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception))) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - SAVE_OPLINE(); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); - } else { - ZEND_VM_SMART_BRANCH(result, 0); - } + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - uint32_t fetch_type; - zend_class_entry *called_scope, *scope; USE_OPLINE + zval *op1, *op2, *result; - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - SAVE_OPLINE(); - zval *op = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(Z_TYPE_P(op) != IS_OBJECT)) { - ZVAL_DEREF(op); - if (Z_TYPE_P(op) != IS_OBJECT) { - zend_type_error("Cannot use \"::class\" on %s", zend_zval_value_name(op)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } - - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op)->name); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - - fetch_type = opline->op1.num; - scope = EX(func)->op_array.scope; - if (UNEXPECTED(scope == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", - fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : - fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + fast_long_add_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); +} - switch (fetch_type) { - case ZEND_FETCH_CLASS_SELF: - ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->name); - break; - case ZEND_FETCH_CLASS_PARENT: - if (UNEXPECTED(scope->parent == NULL)) { - SAVE_OPLINE(); - zend_throw_error(NULL, - "Cannot use \"parent\" when current class scope has no parent"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->parent->name); - break; - case ZEND_FETCH_CLASS_STATIC: - if (Z_TYPE(EX(This)) == IS_OBJECT) { - called_scope = Z_OBJCE(EX(This)); - } else { - called_scope = Z_CE(EX(This)); - } - ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name); - break; - EMPTY_SWITCH_DEFAULT_CASE() - } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *op1, *op2, *result; - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); op2 = RT_CONSTANT(opline, opline->op2); - div_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + result = EX_VAR(opline->result.var); + ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *op1, *op2, *result; - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); op2 = RT_CONSTANT(opline, opline->op2); - pow_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + result = EX_VAR(opline->result.var); + fast_long_sub_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *op1, *op2, *result; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); op2 = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + ZVAL_LONG(result, Z_LVAL_P(op1) * Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} - if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { - zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); - } - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } - ZEND_VM_NEXT_OPCODE(); - } else { - SAVE_OPLINE(); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + zend_long overflow; - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = ZVAL_UNDEFINED_OP1(); - } - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = ZVAL_UNDEFINED_OP2(); - } - concat_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); + Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; + ZEND_VM_NEXT_OPCODE(); +} +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - double d1, d2; + bool result; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - double d1, d2; + bool result; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - double d1, d2; + bool result; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - double d1, d2; + bool result; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - double d1, d2; + bool result; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - double d1, d2; + bool result; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); op2 = RT_CONSTANT(opline, opline->op2); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && IS_CONST == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; + bool result; - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); op2 = RT_CONSTANT(opline, opline->op2); - compare_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; + bool result; - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); op2 = RT_CONSTANT(opline, opline->op2); - boolean_xor_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container, *dim, *value; + zval *op1, *op2; + bool result; - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - dim = RT_CONSTANT(opline, opline->op2); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, BP_VAR_R EXECUTE_DATA_CC); - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_array; - } else { - goto fetch_dim_r_slow; - } - } else { -fetch_dim_r_slow: - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); - } - } else { - zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); - } + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; + zval *op1; + bool result; - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_IS(container, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); + op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC); + result = Z_TYPE_P(op1) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(op1)) == 0; + FREE_OP(opline->op1_type, opline->op1.var); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_SMART_BRANCH_NONE(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - void **cache_slot = NULL; + zval *op1; + bool result; - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC); + result = Z_TYPE_P(op1) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(op1)) == 0; + FREE_OP(opline->op1_type, opline->op1.var); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - break; - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_wrong_property_read(container, RT_CONSTANT(opline, opline->op2)); - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_r_finish; - } while (0); - } - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} - if (IS_CONST == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1; + bool result; - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC); + result = Z_TYPE_P(op1) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(op1)) == 0; + FREE_OP(opline->op1_type, opline->op1.var); - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_r_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { -fetch_obj_r_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - prop_offset = prop_info->offset; - goto fetch_obj_r_simple; - } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { - zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; - ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); - ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); - uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if ((IS_TMP_VAR|IS_VAR) & IS_CV) { - GC_ADDREF(zobj); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR|IS_TMP_VAR)) { - call_info |= ZEND_CALL_RELEASE_THIS; - } - zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); - call->prev_execute_data = execute_data; - call->call = NULL; - call->return_value = EX_VAR(opline->result.var); - call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} - execute_data = call; - EG(current_execute_data) = execute_data; - zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1; + bool result; -#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) - opline = hook->op_array.opcodes; -#else - EX(opline) = hook->op_array.opcodes; -#endif - LOAD_OPLINE_EX(); + op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC); + result = Z_TYPE_P(op1) != IS_ARRAY || zend_hash_num_elements(Z_ARR_P(op1)) > 0; + FREE_OP(opline->op1_type, opline->op1.var); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1; + bool result; - ZEND_VM_ENTER_EX(); - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC); + result = Z_TYPE_P(op1) != IS_ARRAY || zend_hash_num_elements(Z_ARR_P(op1)) > 0; + FREE_OP(opline->op1_type, opline->op1.var); - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; - } - } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_r_copy; - } else { - goto fetch_obj_r_fast_copy; - } - } - } - } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; - } - } + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} -#if ZEND_DEBUG - /* For non-standard object handlers, verify a declared property type in debug builds. - * Fetch prop_info before calling read_property(), as it may deallocate the object. */ - zend_property_info *prop_info = NULL; - if (zobj->handlers->read_property != zend_std_read_property) { - prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); - } -#endif - retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); -#if ZEND_DEBUG - if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO - && ZEND_TYPE_IS_SET(prop_info->type)) { - ZVAL_OPT_DEREF(retval); - zend_verify_property_type(prop_info, retval, /* strict */ true); - } -#endif +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1; + bool result; - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + op1 = _get_zval_ptr_tmpvarcv(opline->op1_type, opline->op1, BP_VAR_R EXECUTE_DATA_CC); + result = Z_TYPE_P(op1) != IS_ARRAY || zend_hash_num_elements(Z_ARR_P(op1)) > 0; + FREE_OP(opline->op1_type, opline->op1.var); - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_r_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } - } while (0); -fetch_obj_r_finish: + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - void **cache_slot = NULL; + zval *op1, *op2; + bool result; - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - break; - } - } - if (IS_CONST == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { - ZVAL_UNDEFINED_OP2(); - } - ZVAL_NULL(EX_VAR(opline->result.var)); - goto fetch_obj_is_finish; - } while (0); - } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - /* here we are sure we are dealing with an object */ - do { - zend_object *zobj = Z_OBJ_P(container); - zend_string *name, *tmp_name; - zval *retval; + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} - if (IS_CONST == IS_CONST) { - cache_slot = CACHE_ADDR(opline->extended_value); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { -fetch_obj_is_simple: - retval = OBJ_PROP(zobj, prop_offset); - if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { -fetch_obj_is_fast_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - ZEND_VM_NEXT_OPCODE(); - } - } - } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { - zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - goto fetch_obj_is_simple; - } - /* Fall through to read_property for hooks. */ - } else if (EXPECTED(zobj->properties != NULL)) { - ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { - uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { - Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} - if (EXPECTED(p->key == name) || - (EXPECTED(p->h == ZSTR_H(name)) && - EXPECTED(p->key != NULL) && - EXPECTED(zend_string_equal_content(p->key, name)))) { - retval = &p->val; - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } - } - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); - } - retval = zend_hash_find_known_hash(zobj->properties, name); - if (EXPECTED(retval)) { - uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; - CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); - if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { - goto fetch_obj_is_copy; - } else { - goto fetch_obj_is_fast_copy; - } - } - } - } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; - } - } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_is_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } - } while (0); + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} -fetch_obj_is_finish: +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - zend_string *op1_str, *op2_str, *str; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); op2 = RT_CONSTANT(opline, opline->op2); - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } - ZEND_VM_NEXT_OPCODE(); - } + op1 = EX_VAR(opline->op1.var); + op2 = RT_CONSTANT(opline, opline->op2); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - op1_str = Z_STR_P(op1); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - op1_str = zend_string_copy(Z_STR_P(op1)); - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - op1_str = zval_get_string_func(op1); - } - if (IS_CONST == IS_CONST) { - op2_str = Z_STR_P(op2); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - op2_str = zend_string_copy(Z_STR_P(op2)); - } else { - if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - } - op2_str = zval_get_string_func(op2); - } - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CONST == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { - GC_ADDREF(op2_str); - } - } - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - zend_string_release_ex(op1_str, 0); - break; - } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + double d1, d2; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + fast_long_add_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto add_double; } - if (IS_CONST != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { - GC_ADDREF(op1_str); - } - } - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - zend_string_release_ex(op2_str, 0); - break; - } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +add_double: + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, d1 + d2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto add_double; } - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + } - ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release_ex(op1_str, 0); + ZEND_VM_DISPATCH_TO_HELPER(zend_add_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + double d1, d2; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + fast_long_sub_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto sub_double; } - if (IS_CONST != IS_CONST) { - zend_string_release_ex(op2_str, 0); + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +sub_double: + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, d1 - d2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto sub_double; } - } while (0); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_DISPATCH_TO_HELPER(zend_sub_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zval *object; - zend_function *fbc; - zend_class_entry *called_scope; - zend_object *obj; - zend_execute_data *call; - uint32_t call_info; - - SAVE_OPLINE(); + zval *op1, *op2, *result; + double d1, d2; - object = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + zend_long overflow; - if (IS_CONST != IS_CONST) { - function_name = RT_CONSTANT(opline, opline->op2); + result = EX_VAR(opline->result.var); + ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); + Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto mul_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +mul_double: + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, d1 * d2); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto mul_double; + } } - if (IS_CONST != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Method name must be a string"); + ZEND_VM_DISPATCH_TO_HELPER(zend_mul_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MOD_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } while (0); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + result = EX_VAR(opline->result.var); + if (UNEXPECTED(Z_LVAL_P(op2) == 0)) { + ZEND_VM_TAIL_CALL(zend_mod_by_zero_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) { + /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */ + ZVAL_LONG(result, 0); + } else { + ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2)); + } + ZEND_VM_NEXT_OPCODE(); + } } - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - obj = Z_OBJ_P(object); - } else { - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - } else { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - zend_reference *ref = Z_REF_P(object); + ZEND_VM_DISPATCH_TO_HELPER(zend_mod_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} - object = &ref->val; - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) & IS_VAR) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_ADDREF_P(object); - } - } - break; - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - object = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CONST != IS_CONST) { +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) + && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { + /* Perform shift on unsigned numbers to get well-defined wrap behavior. */ + ZVAL_LONG(EX_VAR(opline->result.var), + (zend_long) ((zend_ulong) Z_LVAL_P(op1) << Z_LVAL_P(op2))); + ZEND_VM_NEXT_OPCODE(); + } - } - HANDLE_EXCEPTION(); - } - } - if (IS_CONST == IS_CONST) { - function_name = RT_CONSTANT(opline, opline->op2); - } - zend_invalid_method_call(object, function_name); + ZEND_VM_DISPATCH_TO_HELPER(zend_shift_left_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } while (0); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG) + && EXPECTED((zend_ulong)Z_LVAL_P(op2) < SIZEOF_ZEND_LONG * 8)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) >> Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); } - called_scope = obj->ce; + ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} - if (IS_CONST == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else { - zend_object *orig_obj = obj; +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; - if (IS_CONST == IS_CONST) { - function_name = RT_CONSTANT(opline, opline->op2); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { +is_smaller_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { +is_smaller_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_double; } - - /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_double: + if (d1 < d2) { + goto is_smaller_true; + } else { + goto is_smaller_false; } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_double; + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { +is_smaller_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { +is_smaller_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); } - HANDLE_EXCEPTION(); - } - if (IS_CONST == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_double; } - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ - if (GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_double: + if (d1 < d2) { + goto is_smaller_true; + } else { + goto is_smaller_false; } - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_double; } } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} - if (IS_CONST != IS_CONST) { - - - } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { - zend_objects_store_del(obj); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) < Z_LVAL_P(op2))) { +is_smaller_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + } else { +is_smaller_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_double; } - /* call static method */ - obj = (zend_object*)called_scope; - call_info = ZEND_CALL_NESTED_FUNCTION; - } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_double: + if (d1 < d2) { + goto is_smaller_true; + } else { + goto is_smaller_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_double; } - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; } - - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, obj); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value, *arg; + zval *op1, *op2; + double d1, d2; - if (IS_CONST == IS_CONST) { - SAVE_OPLINE(); - zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - uint32_t arg_num; - arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); - if (UNEXPECTED(!arg)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { +is_smaller_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { +is_smaller_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_or_equal_double: + if (d1 <= d2) { + goto is_smaller_or_equal_true; + } else { + goto is_smaller_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_or_equal_double; } - } else { - arg = ZEND_CALL_VAR(EX(call), opline->result.var); } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - ZVAL_COPY_VALUE(arg, value); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { - Z_ADDREF_P(arg); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { +is_smaller_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else { +is_smaller_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_smaller_or_equal_double; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_smaller_or_equal_double: + if (d1 <= d2) { + goto is_smaller_or_equal_true; + } else { + goto is_smaller_or_equal_false; + } + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_smaller_or_equal_double; } } - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; double d1, d2; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -case_true: - ZEND_VM_SMART_BRANCH_TRUE(); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) <= Z_LVAL_P(op2))) { +is_smaller_or_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); } else { -case_false: - ZEND_VM_SMART_BRANCH_FALSE(); +is_smaller_or_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + ZVAL_FALSE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { d1 = (double)Z_LVAL_P(op1); d2 = Z_DVAL_P(op2); - goto case_double; + goto is_smaller_or_equal_double; } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_DOUBLE)) { d1 = Z_DVAL_P(op1); d2 = Z_DVAL_P(op2); -case_double: - if (d1 == d2) { - goto case_true; +is_smaller_or_equal_double: + if (d1 <= d2) { + goto is_smaller_or_equal_true; } else { - goto case_false; + goto is_smaller_or_equal_false; } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + } else if (EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { d1 = Z_DVAL_P(op1); d2 = (double)Z_LVAL_P(op2); - goto case_double; + goto is_smaller_or_equal_double; } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_OR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; - if (result) { - goto case_true; - } else { - goto case_false; - } - } + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) | Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); } - ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + + ZEND_VM_DISPATCH_TO_HELPER(zend_bw_or_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_AND_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - bool result; - zend_ulong hval; - zval *offset; + zval *op1, *op2; - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = RT_CONSTANT(opline, opline->op2); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) & Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; - zval *value; - zend_string *str; + ZEND_VM_DISPATCH_TO_HELPER(zend_bw_and_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} -isset_dim_obj_array: - ht = Z_ARRVAL_P(container); -isset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_CONST != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index_prop; - } - } - value = zend_hash_find_ex(ht, str, IS_CONST == IS_CONST); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_prop: - value = zend_hash_index_find(ht, hval); - } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { - offset = Z_REFVAL_P(offset); - goto isset_again; - } else { - value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); - if (UNEXPECTED(EG(exception))) { - result = 0; - goto isset_dim_obj_exit; - } - } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; - if (!(opline->extended_value & ZEND_ISEMPTY)) { - /* > IS_NULL means not IS_UNDEF and not IS_NULL */ - result = value != NULL && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + if (1 && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && (IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_INFO_P(op1) == IS_LONG) + && EXPECTED(Z_TYPE_INFO_P(op2) == IS_LONG)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(op1) ^ Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); + } - if ((IS_TMP_VAR|IS_VAR) & (IS_CONST|IS_CV)) { - /* avoid exception check */ + ZEND_VM_DISPATCH_TO_HELPER(zend_bw_xor_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; - ZEND_VM_SMART_BRANCH(result, 0); - } - } else { - result = (value == NULL || !i_zend_is_true(value)); - } - goto isset_dim_obj_exit; - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto isset_dim_obj_array; - } - } + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} - if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - if (!(opline->extended_value & ZEND_ISEMPTY)) { - result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); - } else { - result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); - } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; -isset_dim_obj_exit: + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + fast_long_add_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); +} +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - int result; - zval *offset; - zend_string *name, *tmp_name; + zval *op1, *op2, *result; - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = RT_CONSTANT(opline, opline->op2); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } - } else { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } - } +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; - if (IS_CONST == IS_CONST) { - name = Z_STR_P(offset); - } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - result = 0; - goto isset_object_finish; - } - } + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + fast_long_sub_function(result, op1, op2); + ZEND_VM_NEXT_OPCODE(); +} - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} -isset_object_finish: +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + ZVAL_LONG(result, Z_LVAL_P(op1) * Z_LVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2, *result; + zend_long overflow; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow); + Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG; + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *op1, *op2, *result; - zval *key, *subject; - HashTable *ht; + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = EX_VAR(opline->result.var); + ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; bool result; - SAVE_OPLINE(); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} - key = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - subject = RT_CONSTANT(opline, opline->op2); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { -array_key_exists_array: - ht = Z_ARRVAL_P(subject); - result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); - } else { - if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { - subject = Z_REFVAL_P(subject); - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { - goto array_key_exists_array; - } - } - zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); - result = 0; - } + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) == Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *expr; + zval *op1, *op2; bool result; - SAVE_OPLINE(); - expr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} -try_instanceof: - if (Z_TYPE_P(expr) == IS_OBJECT) { - zend_class_entry *ce; +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - if (IS_CONST == IS_CONST) { - ce = CACHED_PTR(opline->extended_value); - if (UNEXPECTED(ce == NULL)) { - ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (EXPECTED(ce)) { - CACHE_PTR(opline->extended_value, ce); - } - } - } else if (IS_CONST == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - result = ce && instanceof_function(Z_OBJCE_P(expr), ce); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { - expr = Z_REFVAL_P(expr); - goto try_instanceof; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - result = 0; - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container, *dim, *value; - zend_long offset; - HashTable *ht; + zval *op1, *op2; + bool result; - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - dim = RT_CONSTANT(opline, opline->op2); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_index_array: - if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { - offset = Z_LVAL_P(dim); - } else { - SAVE_OPLINE(); - zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - ht = Z_ARRVAL_P(container); - ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - SAVE_OPLINE(); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_index_array; - } else { - goto fetch_dim_r_index_slow; - } - } else { -fetch_dim_r_index_slow: - SAVE_OPLINE(); - if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) == Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} -fetch_dim_r_index_undef: - ZVAL_NULL(EX_VAR(opline->result.var)); - SAVE_OPLINE(); - zend_undefined_offset(offset); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container, *dim, *value; - zend_long offset; - HashTable *ht; + zval *op1, *op2; + bool result; - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - dim = EX_VAR(opline->op2.var); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { -fetch_dim_r_index_array: - if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { - offset = Z_LVAL_P(dim); - } else { - SAVE_OPLINE(); - zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - ht = Z_ARRVAL_P(container); - ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - SAVE_OPLINE(); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto fetch_dim_r_index_array; - } else { - goto fetch_dim_r_index_slow; - } - } else { -fetch_dim_r_index_slow: - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) != Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; -fetch_dim_r_index_undef: - ZVAL_NULL(EX_VAR(opline->result.var)); - SAVE_OPLINE(); - zend_undefined_offset(offset); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; + bool result; - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - div_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; + bool result; - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - pow_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) != Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; + bool result; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); +} - if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { - zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); - } - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } - ZEND_VM_NEXT_OPCODE(); - } else { - SAVE_OPLINE(); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = ZVAL_UNDEFINED_OP1(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = ZVAL_UNDEFINED_OP2(); - } - concat_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) < Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - double d1, d2; + bool result; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - double d1, d2; + bool result; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - double d1, d2; + bool result; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -is_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - } else { -is_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_equal_double: - if (d1 == d2) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (result) { - goto is_equal_true; - } else { - goto is_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) < Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - double d1, d2; + bool result; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_NONE(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_NONE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - double d1, d2; + bool result; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - double d1, d2; + bool result; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && (IS_TMP_VAR|IS_VAR) == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { - /* pass */ - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { -is_not_equal_true: - ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); - } else { -is_not_equal_false: - ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -is_not_equal_double: - if (d1 != d2) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto is_not_equal_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op2); - } - if (!result) { - goto is_not_equal_true; - } else { - goto is_not_equal_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_NONE(result, 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPZ(result, 0); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; + bool result; + + op1 = EX_VAR(opline->op1.var); + op2 = EX_VAR(opline->op2.var); + result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2)); + ZEND_VM_SMART_BRANCH_JMPNZ(result, 0); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - compare_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + container = EX_VAR(opline->op1.var); + zend_fetch_dimension_address_LIST_r(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op; + + SAVE_OPLINE(); + op = EX_VAR(opline->op1.var); + zend_match_unhandled_error(op); + HANDLE_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + + SAVE_OPLINE(); + container = EX_VAR(opline->op1.var); + zend_fetch_dimension_address_LIST_r(container, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FREE_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - boolean_xor_function(EX_VAR(opline->result.var), op1, op2); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_FREE_SPEC_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zval *var; + USE_OPLINE + + var = EX_VAR(opline->op1.var); + if (Z_TYPE_P(var) != IS_ARRAY) { + SAVE_OPLINE(); + if (Z_FE_ITER_P(var) != (uint32_t)-1) { + zend_hash_iterator_del(Z_FE_ITER_P(var)); + } + zval_ptr_dtor_nogc(var); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + + /* This is freeing an array. Use an inlined version of zval_ptr_dtor_nogc. */ + /* PHP only needs to save the opline and check for an exception if the last reference to the array was garbage collected (destructors of elements in the array could throw an exception) */ + if (Z_REFCOUNTED_P(var) && !Z_DELREF_P(var)) { + SAVE_OPLINE(); + rc_dtor_func(Z_COUNTED_P(var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container, *dim, *value; SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) & (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 = RT_CONSTANT(opline, opline->op2); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R EXECUTE_DATA_CC); + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, 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 ((IS_TMP_VAR|IS_VAR) == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { goto fetch_dim_r_array; @@ -73758,33 +68305,37 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_T } } else { fetch_dim_r_slow: - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); } } else { - zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_read_IS(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + /* 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, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -73792,11 +68343,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_T SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) & (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 ((IS_TMP_VAR|IS_VAR) == IS_CONST || ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + if (((IS_TMP_VAR|IS_VAR) & IS_CV) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; @@ -73805,7 +68360,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_T if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - zend_wrong_property_read(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + zend_wrong_property_read(container, RT_CONSTANT(opline, opline->op2)); ZVAL_NULL(EX_VAR(opline->result.var)); goto fetch_obj_r_finish; } while (0); @@ -73817,7 +68372,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_T zend_string *name, *tmp_name; zval *retval; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_CONST == IS_CONST) { cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { @@ -73877,7 +68432,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_T /* Fall through to read_property for hooks. */ } else if (EXPECTED(zobj->properties != NULL)) { ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); @@ -73910,9 +68465,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_T } } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); if (UNEXPECTED(!name)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); break; @@ -73936,7 +68491,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_T } #endif - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_CONST != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -73949,12 +68504,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_T } while (0); fetch_obj_r_finish: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -73962,6 +68518,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ if ((IS_TMP_VAR|IS_VAR) == IS_CONST || ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -73972,7 +68530,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ break; } } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { + if (IS_CONST == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); } ZVAL_NULL(EX_VAR(opline->result.var)); @@ -73986,7 +68544,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ zend_string *name, *tmp_name; zval *retval; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_CONST == IS_CONST) { cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { @@ -74013,7 +68571,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ /* Fall through to read_property for hooks. */ } else if (EXPECTED(zobj->properties != NULL)) { ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); @@ -74046,614 +68604,42 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ } } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - break; - } - } - - retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_is_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } - } while (0); - -fetch_obj_is_finish: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - zend_string *op1_str, *op2_str, *str; - - - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); - - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } - ZEND_VM_NEXT_OPCODE(); - } - - SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - op1_str = Z_STR_P(op1); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - op1_str = zend_string_copy(Z_STR_P(op1)); - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - op1_str = zval_get_string_func(op1); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - op2_str = Z_STR_P(op2); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - op2_str = zend_string_copy(Z_STR_P(op2)); - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - } - op2_str = zval_get_string_func(op2); - } - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { - GC_ADDREF(op2_str); - } - } - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - zend_string_release_ex(op1_str, 0); - break; - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { - GC_ADDREF(op1_str); - } - } - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - zend_string_release_ex(op2_str, 0); - break; - } - } - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - - ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release_ex(op1_str, 0); - } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release_ex(op2_str, 0); - } - } while (0); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *function_name; - zval *object; - zend_function *fbc; - zend_class_entry *called_scope; - zend_object *obj; - zend_execute_data *call; - uint32_t call_info; - - SAVE_OPLINE(); - - object = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - } - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - break; - } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } - zend_throw_error(NULL, "Method name must be a string"); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } while (0); - } - - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - obj = Z_OBJ_P(object); - } else { - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - } else { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - zend_reference *ref = Z_REF_P(object); - - object = &ref->val; - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) & IS_VAR) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_ADDREF_P(object); - } - } - break; - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - object = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } - HANDLE_EXCEPTION(); - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - } - zend_invalid_method_call(object, function_name); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } while (0); - } - - called_scope = obj->ce; - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else { - zend_object *orig_obj = obj; - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - } - - /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); - } - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); - } - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ - if (GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); - } - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - } - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } - - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { - zend_objects_store_del(obj); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - } - /* call static method */ - obj = (zend_object*)called_scope; - call_info = ZEND_CALL_NESTED_FUNCTION; - } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ - } - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; - } - - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, obj); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - double d1, d2; - - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -case_true: - ZEND_VM_SMART_BRANCH_TRUE(); - } else { -case_false: - ZEND_VM_SMART_BRANCH_FALSE(); - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto case_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -case_double: - if (d1 == d2) { - goto case_true; - } else { - goto case_false; - } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto case_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - if (result) { - goto case_true; - } else { - goto case_false; - } - } - } - ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - bool result; - zend_ulong hval; - zval *offset; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; - zval *value; - zend_string *str; - -isset_dim_obj_array: - ht = Z_ARRVAL_P(container); -isset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index_prop; - } - } - value = zend_hash_find_ex(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_prop: - value = zend_hash_index_find(ht, hval); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { - offset = Z_REFVAL_P(offset); - goto isset_again; - } else { - value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); - if (UNEXPECTED(EG(exception))) { - result = 0; - goto isset_dim_obj_exit; - } - } - - if (!(opline->extended_value & ZEND_ISEMPTY)) { - /* > IS_NULL means not IS_UNDEF and not IS_NULL */ - result = value != NULL && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - - if ((IS_TMP_VAR|IS_VAR) & (IS_CONST|IS_CV)) { - /* avoid exception check */ - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 0); - } - } else { - result = (value == NULL || !i_zend_is_true(value)); - } - goto isset_dim_obj_exit; - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto isset_dim_obj_array; - } - } - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - if (!(opline->extended_value & ZEND_ISEMPTY)) { - result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); - } else { - result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); - } - -isset_dim_obj_exit: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *container; - int result; - zval *offset; - zend_string *name, *tmp_name; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } - } else { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } - } - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(offset); - } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - result = 0; - goto isset_object_finish; - } - } - - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -isset_object_finish: - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *key, *subject; - HashTable *ht; - bool result; - - SAVE_OPLINE(); - - key = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - subject = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { -array_key_exists_array: - ht = Z_ARRVAL_P(subject); - result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); - } else { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { - subject = Z_REFVAL_P(subject); - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { - goto array_key_exists_array; - } - } - zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); - result = 0; - } - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *expr; - bool result; - - SAVE_OPLINE(); - expr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - -try_instanceof: - if (Z_TYPE_P(expr) == IS_OBJECT) { - zend_class_entry *ce; - - if (IS_VAR == IS_CONST) { - ce = CACHED_PTR(opline->extended_value); - if (UNEXPECTED(ce == NULL)) { - ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (EXPECTED(ce)) { - CACHE_PTR(opline->extended_value, ce); - } - } - } else if (IS_VAR == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } + name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); - } - result = ce && instanceof_function(Z_OBJCE_P(expr), ce); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { - expr = Z_REFVAL_P(expr); - goto try_instanceof; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + break; + } } - result = 0; - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX int type); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R)); -} + retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W)); -} + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW)); -} + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_is_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } + } while (0); -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - int fetch_type = - (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ? - BP_VAR_W : BP_VAR_R; - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX fetch_type)); -} +fetch_obj_is_finish: -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET)); -} -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *value, *arg; - if (IS_UNUSED == IS_CONST) { + if (IS_CONST == IS_CONST) { SAVE_OPLINE(); zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); uint32_t arg_num; @@ -74676,377 +68662,540 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_V ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *varname; - zend_string *name, *tmp_name; - HashTable *target_symbol_table; + zval *container, *dim, *value; + zend_long offset; + HashTable *ht; + + container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + dim = RT_CONSTANT(opline, opline->op2); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + ht = Z_ARRVAL_P(container); + ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; + } + } else { +fetch_dim_r_index_slow: + SAVE_OPLINE(); + if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); SAVE_OPLINE(); + zend_undefined_offset(offset); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - varname = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container, *dim, *value; + zend_long offset; + HashTable *ht; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(varname); - } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { - name = Z_STR_P(varname); - tmp_name = NULL; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { - varname = ZVAL_UNDEFINED_OP1(); + container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + dim = EX_VAR(opline->op2.var); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_index_array: + if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { + offset = Z_LVAL_P(dim); + } else { + SAVE_OPLINE(); + zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - name = zval_try_get_tmp_string(varname, &tmp_name); - if (UNEXPECTED(!name)) { + ht = Z_ARRVAL_P(container); + ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef); + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_index_array; + } else { + goto fetch_dim_r_index_slow; + } + } else { +fetch_dim_r_index_slow: + SAVE_OPLINE(); + if ((IS_TMP_VAR|IS_VAR|IS_CV) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; } + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } - target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); - zend_hash_del_ind(target_symbol_table, name); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } +fetch_dim_r_index_undef: + ZVAL_NULL(EX_VAR(opline->result.var)); + SAVE_OPLINE(); + zend_undefined_offset(offset); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - bool result; - zval *varname; - zend_string *name, *tmp_name; - HashTable *target_symbol_table; + zval *container, *dim, *value; SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - name = Z_STR_P(varname); - } else { - name = zval_get_tmp_string(varname, &tmp_name); + container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) & (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); } - - target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); - value = zend_hash_find_ex(target_symbol_table, name, (IS_TMP_VAR|IS_VAR) == IS_CONST); - + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - if (!value) { - result = (opline->extended_value & ZEND_ISEMPTY); - } else { - if (Z_TYPE_P(value) == IS_INDIRECT) { - value = Z_INDIRECT_P(value); - } - if (!(opline->extended_value & ZEND_ISEMPTY)) { - if (Z_ISREF_P(value)) { - value = Z_REFVAL_P(value); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { +fetch_dim_r_array: + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_TMP_VAR, BP_VAR_R EXECUTE_DATA_CC); + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto fetch_dim_r_array; + } else { + goto fetch_dim_r_slow; } - result = Z_TYPE_P(value) > IS_NULL; } else { - result = !i_zend_is_true(value); +fetch_dim_r_slow: + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); } + } else { + zend_fetch_dimension_address_read_R(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - ZEND_VM_SMART_BRANCH(result, true); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + + SAVE_OPLINE(); + container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + /* 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_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *expr; - bool result; + zval *container; + void **cache_slot = NULL; SAVE_OPLINE(); - expr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) & (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); + } -try_instanceof: - if (Z_TYPE_P(expr) == IS_OBJECT) { - zend_class_entry *ce; + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || + ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if (((IS_TMP_VAR|IS_VAR) & IS_CV) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { + break; + } + } + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_wrong_property_read(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; + } while (0); + } - if (IS_UNUSED == IS_CONST) { - ce = CACHED_PTR(opline->extended_value); - if (UNEXPECTED(ce == NULL)) { - ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); - if (EXPECTED(ce)) { - CACHE_PTR(opline->extended_value, ce); + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; + + if (IS_TMP_VAR == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); + + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_r_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_INFO_P(retval) != IS_UNDEF)) { + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { +fetch_obj_r_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + prop_offset = prop_info->offset; + goto fetch_obj_r_simple; + } else if (EXPECTED(ZEND_IS_PROPERTY_HOOK_SIMPLE_GET(prop_offset))) { + zend_function *hook = prop_info->hooks[ZEND_PROPERTY_HOOK_GET]; + ZEND_ASSERT(hook->type == ZEND_USER_FUNCTION); + ZEND_ASSERT(RUN_TIME_CACHE(&hook->op_array)); + + uint32_t call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if ((IS_TMP_VAR|IS_VAR) & IS_CV) { + GC_ADDREF(zobj); + } + if ((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR|IS_TMP_VAR)) { + call_info |= ZEND_CALL_RELEASE_THIS; + } + zend_execute_data *call = zend_vm_stack_push_call_frame(call_info, hook, 0, zobj); + call->prev_execute_data = execute_data; + call->call = NULL; + call->return_value = EX_VAR(opline->result.var); + call->run_time_cache = RUN_TIME_CACHE(&hook->op_array); + + execute_data = call; + EG(current_execute_data) = execute_data; + zend_init_cvs(0, hook->op_array.last_var EXECUTE_DATA_CC); + +#if defined(ZEND_VM_IP_GLOBAL_REG) && ((ZEND_VM_KIND == ZEND_VM_KIND_CALL) || (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)) + opline = hook->op_array.opcodes; +#else + EX(opline) = hook->op_array.opcodes; +#endif + LOAD_OPLINE_EX(); + + + + + ZEND_VM_ENTER_EX(); + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_r_copy; + } else { + goto fetch_obj_r_fast_copy; + } + } } } - } else if (IS_UNUSED == IS_UNUSED) { - ce = zend_fetch_class(NULL, opline->op2.num); - if (UNEXPECTED(ce == NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + } else { + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); + break; } - } else { - ce = Z_CE_P(EX_VAR(opline->op2.var)); } - result = ce && instanceof_function(Z_OBJCE_P(expr), ce); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { - expr = Z_REFVAL_P(expr); - goto try_instanceof; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + +#if ZEND_DEBUG + /* For non-standard object handlers, verify a declared property type in debug builds. + * Fetch prop_info before calling read_property(), as it may deallocate the object. */ + zend_property_info *prop_info = NULL; + if (zobj->handlers->read_property != zend_std_read_property) { + prop_info = zend_get_property_info(zobj->ce, name, /* silent */ true); } - result = 0; - } +#endif + retval = zobj->handlers->read_property(zobj, name, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); +#if ZEND_DEBUG + if (!EG(exception) && prop_info && prop_info != ZEND_WRONG_PROPERTY_INFO + && ZEND_TYPE_IS_SET(prop_info->type)) { + ZVAL_OPT_DEREF(retval); + zend_verify_property_type(prop_info, retval, /* strict */ true); + } +#endif + + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_r_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } + } while (0); + +fetch_obj_r_finish: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COUNT_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1; - zend_long count; + zval *container; + void **cache_slot = NULL; SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - while (1) { - if (Z_TYPE_P(op1) == IS_ARRAY) { - count = zend_hash_num_elements(Z_ARRVAL_P(op1)); - break; - } else if (Z_TYPE_P(op1) == IS_OBJECT) { - zend_object *zobj = Z_OBJ_P(op1); + container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ - /* first, we check if the handler is defined */ - if (zobj->handlers->count_elements) { - if (SUCCESS == zobj->handlers->count_elements(zobj, &count)) { - break; - } - if (UNEXPECTED(EG(exception))) { - count = 0; + if ((IS_TMP_VAR|IS_VAR) == IS_CONST || + ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + do { + if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; } } + if (IS_TMP_VAR == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { + ZVAL_UNDEFINED_OP2(); + } + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; + } while (0); + } - /* if not and the object implements Countable we call its count() method */ - if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) { - zval retval; + /* here we are sure we are dealing with an object */ + do { + zend_object *zobj = Z_OBJ_P(container); + zend_string *name, *tmp_name; + zval *retval; - zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT)); - zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval); - count = zval_get_long(&retval); - zval_ptr_dtor(&retval); + if (IS_TMP_VAR == IS_CONST) { + cache_slot = CACHE_ADDR(opline->extended_value); + + if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { + uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + + if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { +fetch_obj_is_simple: + retval = OBJ_PROP(zobj, prop_offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { +fetch_obj_is_fast_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + ZEND_VM_NEXT_OPCODE(); + } + } + } else if (UNEXPECTED(IS_HOOKED_PROPERTY_OFFSET(prop_offset))) { + if (ZEND_IS_PROPERTY_HOOK_SIMPLE_READ(prop_offset)) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + prop_offset = prop_info->offset; + goto fetch_obj_is_simple; + } + /* Fall through to read_property for hooks. */ + } else if (EXPECTED(zobj->properties != NULL)) { + ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { + uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); + + if (EXPECTED(idx < zobj->properties->nNumUsed * sizeof(Bucket))) { + Bucket *p = (Bucket*)((char*)zobj->properties->arData + idx); + + if (EXPECTED(p->key == name) || + (EXPECTED(p->h == ZSTR_H(name)) && + EXPECTED(p->key != NULL) && + EXPECTED(zend_string_equal_content(p->key, name)))) { + retval = &p->val; + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } + } + } + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_DYNAMIC_PROPERTY_OFFSET); + } + retval = zend_hash_find_known_hash(zobj->properties, name); + if (EXPECTED(retval)) { + uintptr_t idx = (char*)retval - (char*)zobj->properties->arData; + CACHE_PTR_EX(cache_slot + 1, (void*)ZEND_ENCODE_DYN_PROP_OFFSET(idx)); + if (0 || ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) != 0) { + goto fetch_obj_is_copy; + } else { + goto fetch_obj_is_fast_copy; + } + } + } + } + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); + } else { + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + if (UNEXPECTED(!name)) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); break; } + } + + retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); + + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } - /* If There's no handler and it doesn't implement Countable then emit a TypeError */ - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - continue; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_is_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); } - count = 0; - zend_type_error("%s(): Argument #1 ($value) must be of type Countable|array, %s given", opline->extended_value ? "sizeof" : "count", zend_zval_value_name(op1)); - break; - } + } while (0); - ZVAL_LONG(EX_VAR(opline->result.var), count); +fetch_obj_is_finish: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zend_array *ht = Z_ARRVAL_P(_get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC)); - ZVAL_LONG(EX_VAR(opline->result.var), zend_hash_num_elements(ht)); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR) && !(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - SAVE_OPLINE(); - zend_array_destroy(ht); - if (EG(exception)) { - HANDLE_EXCEPTION(); - } - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *value, *arg; - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_UNUSED == IS_CONST) { SAVE_OPLINE(); - if (UNEXPECTED(!EX(func)->common.scope)) { - zend_throw_error(NULL, "get_class() without arguments must be called from within a class"); - ZVAL_UNDEF(EX_VAR(opline->result.var)); + zend_string *arg_name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); + uint32_t arg_num; + arg = zend_handle_named_arg(&EX(call), arg_name, &arg_num, CACHE_ADDR(opline->result.num)); + if (UNEXPECTED(!arg)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); HANDLE_EXCEPTION(); - } else { - zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated"); - ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } - ZEND_VM_NEXT_OPCODE(); } } else { - zval *op1; + arg = ZEND_CALL_VAR(EX(call), opline->result.var); + } - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - while (1) { - if (Z_TYPE_P(op1) == IS_OBJECT) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - continue; - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - zend_type_error("get_class(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(op1)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - } - break; + value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + ZVAL_COPY_VALUE(arg, value); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(arg))) { + Z_ADDREF_P(arg); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zval *result = EX_VAR(opline->result.var); - ZVAL_COPY(result, value); ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - div_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *varname; + zend_string *name, *tmp_name; + HashTable *target_symbol_table; SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - pow_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_VAR(opline->op2.var); - - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CV == IS_CONST || IS_CV == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); + varname = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { - zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); - } - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } - } - ZEND_VM_NEXT_OPCODE(); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + name = Z_STR_P(varname); + } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { + name = Z_STR_P(varname); + tmp_name = NULL; } else { - SAVE_OPLINE(); - - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - op1 = ZVAL_UNDEFINED_OP1(); + if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + varname = ZVAL_UNDEFINED_OP1(); } - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - op2 = ZVAL_UNDEFINED_OP2(); + name = zval_try_get_tmp_string(varname, &tmp_name); + if (UNEXPECTED(!name)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); } - concat_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } + target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); + zend_hash_del_ind(target_symbol_table, name); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + zend_tmp_string_release(tmp_name); } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - compare_function(EX_VAR(opline->result.var), op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + zval *result = EX_VAR(opline->result.var); + ZVAL_COPY(result, value); + ZEND_VM_NEXT_OPCODE(); } static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -75056,13 +69205,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_T SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) & (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 = EX_VAR(opline->op2.var); if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_array: value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, 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 ((IS_TMP_VAR|IS_VAR) == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { goto fetch_dim_r_array; @@ -75092,6 +69245,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_ SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + /* 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, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); @@ -75107,11 +69262,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_T SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR|IS_VAR) & (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 ((IS_TMP_VAR|IS_VAR) == IS_CONST || ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + if (((IS_TMP_VAR|IS_VAR) & IS_CV) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; @@ -75278,6 +69437,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ SAVE_OPLINE(); container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ if ((IS_TMP_VAR|IS_VAR) == IS_CONST || ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -75371,1204 +69532,1940 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ } } - retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); + + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + + if (retval != EX_VAR(opline->result.var)) { +fetch_obj_is_copy: + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); + } + } while (0); + +fetch_obj_is_finish: + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_NOT_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val; + + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + /* The result and op1 can be the same cv zval */ + const uint32_t orig_val_type = Z_TYPE_INFO_P(val); + ZVAL_TRUE(EX_VAR(opline->result.var)); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } else { + SAVE_OPLINE(); + ZVAL_BOOL(EX_VAR(opline->result.var), !i_zend_is_true(val)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ECHO_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *z; + + SAVE_OPLINE(); + z = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + if (Z_TYPE_P(z) == IS_STRING) { + zend_string *str = Z_STR_P(z); + + if (ZSTR_LEN(str) != 0) { + zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); + } + } else { + zend_string *str = zval_get_string_func(z); + + if (ZSTR_LEN(str) != 0) { + zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_string_release_ex(str, 0); + } + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPZ_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val; + uint8_t op1_type; + + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + } + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } + + SAVE_OPLINE(); + op1_type = IS_TMP_VAR; + if (i_zend_is_true(val)) { + opline++; + } else { + opline = OP_JMP_ADDR(opline, opline->op2); + } + if (op1_type & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_nogc(val); + } + ZEND_VM_JMP(opline); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPNZ_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val; + uint8_t op1_type; + + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + } + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + op1_type = IS_TMP_VAR; + if (i_zend_is_true(val)) { + opline = OP_JMP_ADDR(opline, opline->op2); + } else { + opline++; + } + if (op1_type & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_nogc(val); + } + ZEND_VM_JMP(opline); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPZ_EX_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val; + bool ret; + + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_NEXT_OPCODE(); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + } + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } + + SAVE_OPLINE(); + ret = i_zend_is_true(val); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (ret) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + opline++; + } else { + ZVAL_FALSE(EX_VAR(opline->result.var)); + opline = OP_JMP_ADDR(opline, opline->op2); + } + ZEND_VM_JMP(opline); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMPNZ_EX_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *val; + bool ret; + + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(val) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + ZEND_VM_NEXT_OPCODE(); + } + } + + SAVE_OPLINE(); + ret = i_zend_is_true(val); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (ret) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + opline = OP_JMP_ADDR(opline, opline->op2); + } else { + ZVAL_FALSE(EX_VAR(opline->result.var)); + opline++; + } + ZEND_VM_JMP(opline); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *retval_ptr; + zval *return_value; + + + retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + return_value = EX(return_value); + + + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) { + SAVE_OPLINE(); + retval_ptr = ZVAL_UNDEFINED_OP1(); + if (return_value) { + ZVAL_NULL(return_value); + } + } else if (!return_value) { + if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) { + if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) { + SAVE_OPLINE(); + rc_dtor_func(Z_COUNTED_P(retval_ptr)); + } + } + } else { + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { + ZVAL_COPY_VALUE(return_value, retval_ptr); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) { + Z_ADDREF_P(return_value); + } + } + } else if (IS_TMP_VAR == IS_CV) { + do { + if (Z_OPT_REFCOUNTED_P(retval_ptr)) { + if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { + if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + ZVAL_COPY_VALUE(return_value, retval_ptr); + if (GC_MAY_LEAK(ref)) { + SAVE_OPLINE(); + gc_possible_root(ref); + } + ZVAL_NULL(retval_ptr); + break; + } else { + Z_ADDREF_P(retval_ptr); + } + } else { + retval_ptr = Z_REFVAL_P(retval_ptr); + if (Z_OPT_REFCOUNTED_P(retval_ptr)) { + Z_ADDREF_P(retval_ptr); + } + } + } + ZVAL_COPY_VALUE(return_value, retval_ptr); + } while (0); + } else /* if (IS_TMP_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(retval_ptr))) { + zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + + retval_ptr = Z_REFVAL_P(retval_ptr); + ZVAL_COPY_VALUE(return_value, retval_ptr); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { + Z_ADDREF_P(retval_ptr); + } + } else { + ZVAL_COPY_VALUE(return_value, retval_ptr); + } + } + } + + + + + + + ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_BY_REF_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *retval_ptr; + zval *return_value; + + + SAVE_OPLINE(); + + return_value = EX(return_value); + + + do { + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) || + (IS_TMP_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { + /* Not supposed to happen, but we'll allow it */ + zend_error(E_NOTICE, "Only variable references should be returned by reference"); + + retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (!return_value) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } else { + if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) { + ZVAL_COPY_VALUE(return_value, retval_ptr); + break; + } + + ZVAL_NEW_REF(return_value, retval_ptr); + if (IS_TMP_VAR == IS_CONST) { + Z_TRY_ADDREF_P(retval_ptr); + } + } + break; + } + + retval_ptr = zend_get_bad_ptr(); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + if (IS_TMP_VAR == IS_VAR) { + ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval)); + if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) { + zend_error(E_NOTICE, "Only variable references should be returned by reference"); + if (return_value) { + ZVAL_NEW_REF(return_value, retval_ptr); + } else { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } + break; + } } - if (retval != EX_VAR(opline->result.var)) { -fetch_obj_is_copy: - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); + if (return_value) { + if (Z_ISREF_P(retval_ptr)) { + Z_ADDREF_P(retval_ptr); + } else { + ZVAL_MAKE_REF_EX(retval_ptr, 2); + } + ZVAL_REF(return_value, Z_REF_P(retval_ptr)); } + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); } while (0); -fetch_obj_is_finish: - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + // FIXME: Don't create the ref in the first place? + zend_return_unwrap_ref(execute_data, return_value); + + ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GENERATOR_RETURN_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - zend_string *op1_str, *op2_str, *str; + zval *retval; + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_VAR(opline->op2.var); - if (((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { - zend_string *op1_str = Z_STR_P(op1); - zend_string *op2_str = Z_STR_P(op2); - zend_string *str; - uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + SAVE_OPLINE(); + retval = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CV == IS_CONST || IS_CV == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { - ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); - } else { - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); + /* Copy return value into generator->retval */ + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { + ZVAL_COPY_VALUE(&generator->retval, retval); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) { + Z_ADDREF(generator->retval); } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && (IS_TMP_VAR|IS_VAR) != IS_CV && - !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { - size_t len = ZSTR_LEN(op1_str); + } + } else if (IS_TMP_VAR == IS_CV) { + ZVAL_COPY_DEREF(&generator->retval, retval); + } else /* if (IS_TMP_VAR == IS_VAR) */ { + if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_refcounted *ref = Z_COUNTED_P(retval); - str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); + retval = Z_REFVAL_P(retval); + ZVAL_COPY_VALUE(&generator->retval, retval); + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(retval)) { + Z_ADDREF_P(retval); } } else { - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - GC_ADD_FLAGS(str, flags); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CV & (IS_TMP_VAR|IS_VAR)) { - zend_string_release_ex(op2_str, 0); - } + ZVAL_COPY_VALUE(&generator->retval, retval); } - ZEND_VM_NEXT_OPCODE(); } + + EG(current_execute_data) = EX(prev_execute_data); + + /* Close the generator to free up resources */ + zend_generator_close(generator, 1); + + /* Pass execution back to handling code */ + ZEND_VM_RETURN(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_THROW_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - op1_str = Z_STR_P(op1); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - op1_str = zend_string_copy(Z_STR_P(op1)); - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - op1_str = zval_get_string_func(op1); - } - if (IS_CV == IS_CONST) { - op2_str = Z_STR_P(op2); - } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - op2_str = zend_string_copy(Z_STR_P(op2)); - } else { - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); - } - op2_str = zval_get_string_func(op2); - } + value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { - GC_ADDREF(op2_str); - } + if (IS_TMP_VAR == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + value = Z_REFVAL_P(value); + if (EXPECTED(Z_TYPE_P(value) == IS_OBJECT)) { + break; } - ZVAL_STR(EX_VAR(opline->result.var), op2_str); - zend_string_release_ex(op1_str, 0); - break; } - } - if (IS_CV != IS_CONST) { - if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { - GC_ADDREF(op1_str); - } + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); } - ZVAL_STR(EX_VAR(opline->result.var), op1_str); - zend_string_release_ex(op2_str, 0); - break; } - } - str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); - memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); - memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - - ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); - ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_string_release_ex(op1_str, 0); - } - if (IS_CV != IS_CONST) { - zend_string_release_ex(op2_str, 0); + zend_throw_error(NULL, "Can only throw objects"); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); } } while (0); + + zend_exception_save(); + Z_TRY_ADDREF_P(value); + zend_throw_exception_object(value); + zend_exception_restore(); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_USER_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *arg, *param; + + SAVE_OPLINE(); + arg = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + param = ZEND_CALL_VAR(EX(call), opline->result.var); + if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) { + zend_param_must_be_ref(EX(call)->func, opline->op2.num); + Z_TRY_ADDREF_P(arg); + ZVAL_NEW_REF(param, arg); + } else { + ZVAL_COPY(param, arg); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *function_name; - zval *object; - zend_function *fbc; - zend_class_entry *called_scope; - zend_object *obj; - zend_execute_data *call; - uint32_t call_info; + zval *val; - SAVE_OPLINE(); + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (Z_TYPE_INFO_P(val) == IS_TRUE) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + } else if (EXPECTED(Z_TYPE_INFO_P(val) <= IS_TRUE)) { + /* The result and op1 can be the same cv zval */ + const uint32_t orig_val_type = Z_TYPE_INFO_P(val); + ZVAL_FALSE(EX_VAR(opline->result.var)); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(orig_val_type == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + } else { + SAVE_OPLINE(); + ZVAL_BOOL(EX_VAR(opline->result.var), i_zend_is_true(val)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + ZEND_VM_NEXT_OPCODE(); +} - object = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CLONE_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *obj; + zend_object *zobj; + zend_class_entry *ce, *scope; + zend_function *clone; + zend_object_clone_obj_t clone_call; - if (IS_CV != IS_CONST) { - function_name = EX_VAR(opline->op2.var); - } + SAVE_OPLINE(); + obj = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if (IS_CV != IS_CONST && - UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { - do { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { - function_name = Z_REFVAL_P(function_name); - if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + /* ZEND_CLONE also exists as the clone() function and both implementations must be kept in sync. + * The OPcode intentionally does not support a clone-with property list to keep it simple. */ + + do { + if (IS_TMP_VAR == IS_CONST || + (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(obj)) { + obj = Z_REFVAL_P(obj); + if (EXPECTED(Z_TYPE_P(obj) == IS_OBJECT)) { break; } - } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP2(); + } + ZVAL_UNDEF(EX_VAR(opline->result.var)); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(obj) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); HANDLE_EXCEPTION(); } } - zend_throw_error(NULL, "Method name must be a string"); + zend_type_error("clone(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(obj)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } + } while (0); + zobj = Z_OBJ_P(obj); + ce = zobj->ce; + clone = ce->clone; + clone_call = zobj->handlers->clone_obj; + if (UNEXPECTED(clone_call == NULL)) { + zend_throw_error(NULL, "Trying to clone an uncloneable object of class %s", ZSTR_VAL(ce->name)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + if (clone && !(clone->common.fn_flags & ZEND_ACC_PUBLIC)) { + scope = EX(func)->op_array.scope; + ZEND_ASSERT(!(clone->common.fn_flags & ZEND_ACC_PUBLIC)); + if (!zend_check_method_accessible(clone, scope)) { + zend_bad_method_call(clone, clone->common.function_name, scope); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); HANDLE_EXCEPTION(); - } while (0); + } } - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - obj = Z_OBJ_P(object); - } else { - do { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - } else { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { - zend_reference *ref = Z_REF_P(object); + ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(zobj)); - object = &ref->val; - if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { - obj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) & IS_VAR) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_ADDREF_P(object); - } - } - break; - } - } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { - object = ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CV != IS_CONST) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CAST_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *expr; + zval *result = EX_VAR(opline->result.var); - } - HANDLE_EXCEPTION(); - } - } - if (IS_CV == IS_CONST) { - function_name = EX_VAR(opline->op2.var); + SAVE_OPLINE(); + expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + switch (opline->extended_value) { + case IS_LONG: + ZVAL_LONG(result, zval_get_long(expr)); + break; + case IS_DOUBLE: + ZVAL_DOUBLE(result, zval_get_double(expr)); + break; + case IS_STRING: + ZVAL_STR(result, zval_get_string(expr)); + break; + default: + ZEND_ASSERT(opline->extended_value != _IS_BOOL && "Must use ZEND_BOOL instead"); + if (IS_TMP_VAR & (IS_VAR|IS_CV)) { + ZVAL_DEREF(expr); + } + /* If value is already of correct type, return it directly */ + if (Z_TYPE_P(expr) == opline->extended_value) { + ZVAL_COPY_VALUE(result, expr); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); + } else if (IS_TMP_VAR != IS_TMP_VAR) { + if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); } - zend_invalid_method_call(object, function_name); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + + if (opline->extended_value == IS_ARRAY) { + zend_cast_zval_to_array(result, expr, IS_TMP_VAR); + } else { + ZEND_ASSERT(opline->extended_value == IS_OBJECT); + zend_cast_zval_to_object(result, expr, IS_TMP_VAR); } - } while (0); } - called_scope = obj->ce; + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} - if (IS_CV == IS_CONST && - EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { - fbc = CACHED_PTR(opline->result.num + sizeof(void*)); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INCLUDE_OR_EVAL_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_op_array *new_op_array; + zval *inc_filename; + + SAVE_OPLINE(); + inc_filename = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + new_op_array = zend_include_or_eval(inc_filename, opline->extended_value); + if (UNEXPECTED(EG(exception) != NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (new_op_array != ZEND_FAKE_OP_ARRAY && new_op_array != NULL) { + destroy_op_array(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); + } + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else if (new_op_array == ZEND_FAKE_OP_ARRAY) { + if (RETURN_VALUE_USED(opline)) { + ZVAL_TRUE(EX_VAR(opline->result.var)); + } + } else if (UNEXPECTED(new_op_array == NULL)) { + if (RETURN_VALUE_USED(opline)) { + ZVAL_FALSE(EX_VAR(opline->result.var)); + } + } else if (new_op_array->last == 1 + && new_op_array->opcodes[0].opcode == ZEND_RETURN + && new_op_array->opcodes[0].op1_type == IS_CONST + && EXPECTED(zend_execute_ex == execute_ex)) { + if (RETURN_VALUE_USED(opline)) { + const zend_op *op = new_op_array->opcodes; + + ZVAL_COPY(EX_VAR(opline->result.var), RT_CONSTANT(op, op->op1)); + } + zend_destroy_static_vars(new_op_array); + destroy_op_array(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); } else { - zend_object *orig_obj = obj; + zval *return_value = NULL; + zend_execute_data *call; + if (RETURN_VALUE_USED(opline)) { + return_value = EX_VAR(opline->result.var); + } - if (IS_CV == IS_CONST) { - function_name = EX_VAR(opline->op2.var); + new_op_array->scope = EX(func)->op_array.scope; + + call = zend_vm_stack_push_call_frame( + (Z_TYPE_INFO(EX(This)) & ZEND_CALL_HAS_THIS) | ZEND_CALL_NESTED_CODE | ZEND_CALL_HAS_SYMBOL_TABLE, + (zend_function*)new_op_array, 0, + Z_PTR(EX(This))); + + if (EX_CALL_INFO() & ZEND_CALL_HAS_SYMBOL_TABLE) { + call->symbol_table = EX(symbol_table); + } else { + call->symbol_table = zend_rebuild_symbol_table(); } - /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); - if (UNEXPECTED(fbc == NULL)) { - if (EXPECTED(!EG(exception))) { - zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); - } + call->prev_execute_data = execute_data; + i_init_code_execute_data(call, new_op_array, return_value); - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); - } + if (EXPECTED(zend_execute_ex == execute_ex)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_ENTER(); + } else { + ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP); + zend_execute_ex(call); + zend_vm_stack_free_call_frame(call); + } + + zend_destroy_static_vars(new_op_array); + destroy_op_array(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); + if (UNEXPECTED(EG(exception) != NULL)) { + zend_rethrow_exception(execute_data); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + UNDEF_RESULT(); HANDLE_EXCEPTION(); } - if (IS_CV == IS_CONST && - EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && - EXPECTED(obj == orig_obj)) { - CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_R_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *array_ptr, *result; + + SAVE_OPLINE(); + + array_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { + result = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(result, array_ptr); + if (IS_TMP_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) { + Z_ADDREF_P(array_ptr); } - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { - GC_ADDREF(obj); /* For $this pointer */ - if (GC_DELREF(orig_obj) == 0) { - zend_objects_store_del(orig_obj); + Z_FE_POS_P(result) = 0; + + + ZEND_VM_NEXT_OPCODE(); + } else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { + zend_object *zobj = Z_OBJ_P(array_ptr); + if (!zobj->ce->get_iterator) { + if (UNEXPECTED(zend_object_is_lazy(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (UNEXPECTED(EG(exception))) { + UNDEF_RESULT(); + + + HANDLE_EXCEPTION(); + } + } + HashTable *properties = zobj->properties; + if (properties) { + if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(properties); + } + properties = zobj->properties = zend_array_dup(properties); + } + } else { + properties = zobj->handlers->get_properties(zobj); + } + + result = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(result, array_ptr); + if (IS_TMP_VAR != IS_TMP_VAR) { + Z_ADDREF_P(array_ptr); + } + + if (zend_hash_num_elements(properties) == 0) { + Z_FE_ITER_P(result) = (uint32_t) -1; + + + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } - } - if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { - init_func_run_time_cache(&fbc->op_array); - } - } - if (IS_CV != IS_CONST) { + Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0); - } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; - if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { - zend_objects_store_del(obj); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); + } else if (is_empty) { + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } else { + ZEND_VM_NEXT_OPCODE(); } } - /* call static method */ - obj = (zend_object*)called_scope; - call_info = ZEND_CALL_NESTED_FUNCTION; - } else if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR|IS_CV)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - GC_ADDREF(obj); /* For $this pointer */ - } - /* CV may be changed indirectly (e.g. when it's a reference) */ - call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; + } else { + zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } - - call = zend_vm_stack_push_call_frame(call_info, - fbc, opline->extended_value, obj); - call->prev_execute_data = EX(call); - EX(call) = call; - - ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_RW_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; - double d1, d2; + zval *array_ptr, *array_ref; - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - op2 = EX_VAR(opline->op2.var); - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { -case_true: - ZEND_VM_SMART_BRANCH_TRUE(); - } else { -case_false: - ZEND_VM_SMART_BRANCH_FALSE(); + SAVE_OPLINE(); + + if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { + array_ref = array_ptr = zend_get_bad_ptr(); + if (Z_ISREF_P(array_ref)) { + array_ptr = Z_REFVAL_P(array_ref); + } + } else { + array_ref = array_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + } + + if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { + if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { + if (array_ptr == array_ref) { + ZVAL_NEW_REF(array_ref, array_ref); + array_ptr = Z_REFVAL_P(array_ref); } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = (double)Z_LVAL_P(op1); - d2 = Z_DVAL_P(op2); - goto case_double; + Z_ADDREF_P(array_ref); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); + } else { + array_ref = EX_VAR(opline->result.var); + ZVAL_NEW_REF(array_ref, array_ptr); + array_ptr = Z_REFVAL_P(array_ref); } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { - d1 = Z_DVAL_P(op1); - d2 = Z_DVAL_P(op2); -case_double: - if (d1 == d2) { - goto case_true; + if (IS_TMP_VAR == IS_CONST) { + ZVAL_ARR(array_ptr, zend_array_dup(Z_ARRVAL_P(array_ptr))); + } else { + SEPARATE_ARRAY(array_ptr); + } + Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0); + + + ZEND_VM_NEXT_OPCODE(); + } else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { + if (!Z_OBJCE_P(array_ptr)->get_iterator) { + zend_object *zobj = Z_OBJ_P(array_ptr); + HashTable *properties; + if (UNEXPECTED(zend_object_is_lazy(zobj))) { + zobj = zend_lazy_object_init(zobj); + if (UNEXPECTED(EG(exception))) { + UNDEF_RESULT(); + + + HANDLE_EXCEPTION(); + } + } + if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { + if (array_ptr == array_ref) { + ZVAL_NEW_REF(array_ref, array_ref); + array_ptr = Z_REFVAL_P(array_ref); + } + Z_ADDREF_P(array_ref); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); } else { - goto case_false; + array_ptr = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(array_ptr, array_ref); + } + if (Z_OBJ_P(array_ptr)->properties + && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { + if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { + GC_DELREF(Z_OBJ_P(array_ptr)->properties); + } + Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); } - } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { - d1 = Z_DVAL_P(op1); - d2 = (double)Z_LVAL_P(op2); - goto case_double; - } - } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { - bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + properties = Z_OBJPROP_P(array_ptr); + if (zend_hash_num_elements(properties) == 0) { + Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1; - if (result) { - goto case_true; + + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + } + + Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } else { + bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } else if (is_empty) { + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } else { - goto case_false; + ZEND_VM_NEXT_OPCODE(); } } + } else { + zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); } - ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_FETCH_R_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - bool result; - zend_ulong hval; - zval *offset; - - SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = EX_VAR(opline->op2.var); - - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - HashTable *ht; - zval *value; - zend_string *str; + zval *array; + zval *value; + uint32_t value_type; + HashTable *fe_ht; + HashPosition pos; -isset_dim_obj_array: - ht = Z_ARRVAL_P(container); -isset_again: - if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { - str = Z_STR_P(offset); - if (IS_CV != IS_CONST) { - if (ZEND_HANDLE_NUMERIC(str, hval)) { - goto num_index_prop; - } + array = EX_VAR(opline->op1.var); + if (UNEXPECTED(Z_TYPE_P(array) != IS_ARRAY)) { + ZEND_VM_TAIL_CALL(zend_fe_fetch_object_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + fe_ht = Z_ARRVAL_P(array); + pos = Z_FE_POS_P(array); + if (HT_IS_PACKED(fe_ht)) { + value = fe_ht->arPacked + pos; + while (1) { + if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { + /* reached end of iteration */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } - value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST); - } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { - hval = Z_LVAL_P(offset); -num_index_prop: - value = zend_hash_index_find(ht, hval); - } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { - offset = Z_REFVAL_P(offset); - goto isset_again; - } else { - value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); - if (UNEXPECTED(EG(exception))) { - result = 0; - goto isset_dim_obj_exit; + value_type = Z_TYPE_INFO_P(value); + ZEND_ASSERT(value_type != IS_INDIRECT); + if (EXPECTED(value_type != IS_UNDEF)) { + break; } + pos++; + value++; } + Z_FE_POS_P(array) = pos + 1; + if (RETURN_VALUE_USED(opline)) { + ZVAL_LONG(EX_VAR(opline->result.var), pos); + } + } else { + Bucket *p; - if (!(opline->extended_value & ZEND_ISEMPTY)) { - /* > IS_NULL means not IS_UNDEF and not IS_NULL */ - result = value != NULL && Z_TYPE_P(value) > IS_NULL && - (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); - - if ((IS_TMP_VAR|IS_VAR) & (IS_CONST|IS_CV)) { - /* avoid exception check */ - - - ZEND_VM_SMART_BRANCH(result, 0); + p = fe_ht->arData + pos; + while (1) { + if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { + /* reached end of iteration */ + ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); + ZEND_VM_CONTINUE(); } - } else { - result = (value == NULL || !i_zend_is_true(value)); + pos++; + value = &p->val; + value_type = Z_TYPE_INFO_P(value); + ZEND_ASSERT(value_type != IS_INDIRECT); + if (EXPECTED(value_type != IS_UNDEF)) { + break; + } + p++; } - goto isset_dim_obj_exit; - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { - container = Z_REFVAL_P(container); - if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { - goto isset_dim_obj_array; + Z_FE_POS_P(array) = pos; + if (RETURN_VALUE_USED(opline)) { + if (!p->key) { + ZVAL_LONG(EX_VAR(opline->result.var), p->h); + } else { + ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); + } } } - - if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - if (!(opline->extended_value & ZEND_ISEMPTY)) { - result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); + if (EXPECTED(opline->op2_type == IS_CV)) { + zval *variable_ptr = EX_VAR(opline->op2.var); + SAVE_OPLINE(); + zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); - } + ZVAL_DEREF(value); + value_type = Z_TYPE_INFO_P(value); -isset_dim_obj_exit: + zval *res = EX_VAR(opline->op2.var); + zend_refcounted *gc = Z_COUNTED_P(value); + ZVAL_COPY_VALUE_EX(res, value, gc, value_type); + if (Z_TYPE_INFO_REFCOUNTED(value_type)) { + GC_ADDREF(gc); + } + ZEND_VM_NEXT_OPCODE(); + } +} - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_END_SILENCE_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (E_HAS_ONLY_FATAL_ERRORS(EG(error_reporting)) + && !E_HAS_ONLY_FATAL_ERRORS(Z_LVAL_P(EX_VAR(opline->op1.var)))) { + EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var)); + } + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_SET_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *container; - int result; - zval *offset; - zend_string *name, *tmp_name; + zval *value; + zend_reference *ref = NULL; + bool ret; SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || - ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { - container = Z_REFVAL_P(container); - if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } - } else { - result = (opline->extended_value & ZEND_ISEMPTY); - goto isset_object_finish; - } - } + value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if (IS_CV == IS_CONST) { - name = Z_STR_P(offset); - } else { - name = zval_try_get_tmp_string(offset, &tmp_name); - if (UNEXPECTED(!name)) { - result = 0; - goto isset_object_finish; + if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(value)) { + if (IS_TMP_VAR == IS_VAR) { + ref = Z_REF_P(value); } + value = Z_REFVAL_P(value); } - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + ret = i_zend_is_true(value); - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); + if (UNEXPECTED(EG(exception))) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); } -isset_object_finish: + if (ret) { + zval *result = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(result, value); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); + } else if (IS_TMP_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); + } else if (IS_TMP_VAR == IS_VAR && ref) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(result)) { + Z_ADDREF_P(result); + } + } + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COALESCE_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - - zval *key, *subject; - HashTable *ht; - bool result; + zval *value; + zend_reference *ref = NULL; SAVE_OPLINE(); + value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - key = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - subject = EX_VAR(opline->op2.var); + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { + if (IS_TMP_VAR & IS_VAR) { + ref = Z_REF_P(value); + } + value = Z_REFVAL_P(value); + } - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { -array_key_exists_array: - ht = Z_ARRVAL_P(subject); - result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); - } else { - if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { - subject = Z_REFVAL_P(subject); - if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { - goto array_key_exists_array; + if (Z_TYPE_P(value) > IS_NULL) { + zval *result = EX_VAR(opline->result.var); + ZVAL_COPY_VALUE(result, value); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); + } else if (IS_TMP_VAR == IS_CV) { + if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); + } else if ((IS_TMP_VAR & IS_VAR) && ref) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(result)) { + Z_ADDREF_P(result); } } - zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); - result = 0; + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); } - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + if ((IS_TMP_VAR & IS_VAR) && ref) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } + } + ZEND_VM_NEXT_OPCODE(); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_NULL_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *retval_ptr; - zval *return_value; - + zval *val, *result; - retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - return_value = EX(return_value); + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (Z_TYPE_P(val) > IS_NULL) { + do { + if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + if (Z_TYPE_P(val) <= IS_NULL) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + break; + } + } + ZEND_VM_NEXT_OPCODE(); + } while (0); + } - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) { - SAVE_OPLINE(); - retval_ptr = ZVAL_UNDEFINED_OP1(); - if (return_value) { - ZVAL_NULL(return_value); - } - } else if (!return_value) { - if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) { - if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) { - SAVE_OPLINE(); - rc_dtor_func(Z_COUNTED_P(retval_ptr)); + result = EX_VAR(opline->result.var); + uint32_t short_circuiting_type = opline->extended_value & ZEND_SHORT_CIRCUITING_CHAIN_MASK; + if (EXPECTED(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { + ZVAL_NULL(result); + if (IS_TMP_VAR == IS_CV + && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF) + && (opline->extended_value & ZEND_JMP_NULL_BP_VAR_IS) == 0 + ) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); } } + } else if (short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { + ZVAL_FALSE(result); } else { - if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) { - Z_ADDREF_P(return_value); - } - } - } else if (IS_TMP_VAR == IS_CV) { - do { - if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { - zend_refcounted *ref = Z_COUNTED_P(retval_ptr); - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (GC_MAY_LEAK(ref)) { - SAVE_OPLINE(); - gc_possible_root(ref); - } - ZVAL_NULL(retval_ptr); - break; - } else { - Z_ADDREF_P(retval_ptr); - } - } else { - retval_ptr = Z_REFVAL_P(retval_ptr); - if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } - } - } - ZVAL_COPY_VALUE(return_value, retval_ptr); - } while (0); - } else /* if (IS_TMP_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(retval_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(retval_ptr); + ZEND_ASSERT(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); + ZVAL_TRUE(result); + } - retval_ptr = Z_REFVAL_P(retval_ptr); - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } - } else { - ZVAL_COPY_VALUE(return_value, retval_ptr); + ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); +} + +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + zval *result = EX_VAR(opline->result.var); + + value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + ZVAL_NULL(result); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } + + if (IS_TMP_VAR == IS_CV) { + ZVAL_COPY_DEREF(result, value); + } else if (IS_TMP_VAR == IS_VAR) { + if (UNEXPECTED(Z_ISREF_P(value))) { + ZVAL_COPY_VALUE(result, Z_REFVAL_P(value)); + if (UNEXPECTED(Z_DELREF_P(value) == 0)) { + efree_size(Z_REF_P(value), sizeof(zend_reference)); + } else if (Z_OPT_REFCOUNTED_P(result)) { + Z_ADDREF_P(result); + } + } else { + ZVAL_COPY_VALUE(result, value); + } + } else { + ZVAL_COPY_VALUE(result, value); + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) { + Z_ADDREF_P(result); } } } - - - - - - - ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_BY_REF_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_FROM_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *retval_ptr; - zval *return_value; - + zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); + zval *val; SAVE_OPLINE(); + val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - return_value = EX(return_value); + if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) { + zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator"); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } +yield_from_try_again: + if (Z_TYPE_P(val) == IS_ARRAY) { + ZVAL_COPY_VALUE(&generator->values, val); + if (Z_OPT_REFCOUNTED_P(val)) { + Z_ADDREF_P(val); + } + Z_FE_POS(generator->values) = 0; + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + } else if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(val) == IS_OBJECT && Z_OBJCE_P(val)->get_iterator) { + zend_class_entry *ce = Z_OBJCE_P(val); + if (ce == zend_ce_generator) { + zend_generator *new_gen = (zend_generator *) Z_OBJ_P(val); - do { - if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR)) || - (IS_TMP_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_VALUE)) { - /* Not supposed to happen, but we'll allow it */ - zend_error(E_NOTICE, "Only variable references should be returned by reference"); + Z_ADDREF_P(val); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - retval_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if (!return_value) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (UNEXPECTED(new_gen->execute_data == NULL)) { + zend_throw_error(NULL, "Generator passed to yield from was aborted without proper return and is unable to continue"); + zval_ptr_dtor(val); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else if (Z_ISUNDEF(new_gen->retval)) { + if (UNEXPECTED(zend_generator_get_current(new_gen) == generator)) { + zend_throw_error(NULL, "Impossible to yield from the Generator being currently run"); + zval_ptr_dtor(val); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } else { + zend_generator_yield_from(generator, new_gen); + } } else { - if (IS_TMP_VAR == IS_VAR && UNEXPECTED(Z_ISREF_P(retval_ptr))) { - ZVAL_COPY_VALUE(return_value, retval_ptr); - break; + if (RETURN_VALUE_USED(opline)) { + ZVAL_COPY(EX_VAR(opline->result.var), &new_gen->retval); } + ZEND_VM_NEXT_OPCODE(); + } + } else { + zend_object_iterator *iter = ce->get_iterator(ce, val, 0); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_NEW_REF(return_value, retval_ptr); - if (IS_TMP_VAR == IS_CONST) { - Z_TRY_ADDREF_P(retval_ptr); + if (UNEXPECTED(!iter) || UNEXPECTED(EG(exception))) { + if (!EG(exception)) { + zend_throw_error(NULL, "Object of type %s did not create an Iterator", ZSTR_VAL(ce->name)); } + UNDEF_RESULT(); + HANDLE_EXCEPTION(); } - break; - } - - retval_ptr = zend_get_bad_ptr(); - if (IS_TMP_VAR == IS_VAR) { - ZEND_ASSERT(retval_ptr != &EG(uninitialized_zval)); - if (opline->extended_value == ZEND_RETURNS_FUNCTION && !Z_ISREF_P(retval_ptr)) { - zend_error(E_NOTICE, "Only variable references should be returned by reference"); - if (return_value) { - ZVAL_NEW_REF(return_value, retval_ptr); - } else { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + iter->index = 0; + if (iter->funcs->rewind) { + iter->funcs->rewind(iter); + if (UNEXPECTED(EG(exception) != NULL)) { + OBJ_RELEASE(&iter->std); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); } - break; } - } - if (return_value) { - if (Z_ISREF_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } else { - ZVAL_MAKE_REF_EX(retval_ptr, 2); - } - ZVAL_REF(return_value, Z_REF_P(retval_ptr)); + ZVAL_OBJ(&generator->values, &iter->std); } - + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(val) == IS_REFERENCE) { + val = Z_REFVAL_P(val); + goto yield_from_try_again; + } else { + zend_throw_error(NULL, "Can use \"yield from\" only with arrays and Traversables"); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - } while (0); + UNDEF_RESULT(); + HANDLE_EXCEPTION(); + } + /* This is the default return value + * when the expression is a Generator, it will be overwritten in zend_generator_resume() */ + if (RETURN_VALUE_USED(opline)) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + /* This generator has no send target (though the generator we delegate to might have one) */ + generator->send_target = NULL; + /* The GOTO VM uses a local opline variable. We need to set the opline + * variable in execute_data so we don't resume at an old position. */ + SAVE_OPLINE(); - ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); + ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GENERATOR_RETURN_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_STRLEN_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *retval; - - zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C); - - SAVE_OPLINE(); - retval = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + zval *value; - /* Copy return value into generator->retval */ - if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { - ZVAL_COPY_VALUE(&generator->retval, retval); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED(generator->retval))) { - Z_ADDREF(generator->retval); - } + value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(value); } - } else if (IS_TMP_VAR == IS_CV) { - ZVAL_COPY_DEREF(&generator->retval, retval); - } else /* if (IS_TMP_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_refcounted *ref = Z_COUNTED_P(retval); + ZEND_VM_NEXT_OPCODE(); + } else { + bool strict; - retval = Z_REFVAL_P(retval); - ZVAL_COPY_VALUE(&generator->retval, retval); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(retval)) { - Z_ADDREF_P(retval); + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(value) == IS_REFERENCE) { + value = Z_REFVAL_P(value); + if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { + ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE(); } - } else { - ZVAL_COPY_VALUE(&generator->retval, retval); } - } - - EG(current_execute_data) = EX(prev_execute_data); + SAVE_OPLINE(); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + value = ZVAL_UNDEFINED_OP1(); + } + strict = EX_USES_STRICT_TYPES(); + do { + if (EXPECTED(!strict)) { + zend_string *str; + zval tmp; - /* Close the generator to free up resources */ - zend_generator_close(generator, 1); + if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) { + zend_error(E_DEPRECATED, + "strlen(): Passing null to parameter #1 ($string) of type string is deprecated"); + ZVAL_LONG(EX_VAR(opline->result.var), 0); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + break; + } - /* Pass execution back to handling code */ - ZEND_VM_RETURN(); + ZVAL_COPY(&tmp, value); + if (zend_parse_arg_str_weak(&tmp, &str, 1)) { + ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str)); + zval_ptr_dtor(&tmp); + break; + } + zval_ptr_dtor(&tmp); + } + if (!EG(exception)) { + zend_type_error("strlen(): Argument #1 ($string) must be of type string, %s given", zend_zval_value_name(value)); + } + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } while (0); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_USER_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_TYPE_CHECK_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *arg, *param; - - SAVE_OPLINE(); + zval *value; + int result = 0; - arg = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - param = ZEND_CALL_VAR(EX(call), opline->result.var); - if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) { - zend_param_must_be_ref(EX(call)->func, opline->op2.num); - Z_TRY_ADDREF_P(arg); - ZVAL_NEW_REF(param, arg); + value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { +type_check_resource: + if (opline->extended_value != MAY_BE_RESOURCE + || EXPECTED(NULL != zend_rsrc_list_get_rsrc_type(Z_RES_P(value)))) { + result = 1; + } + } else if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && Z_ISREF_P(value)) { + value = Z_REFVAL_P(value); + if ((opline->extended_value >> (uint32_t)Z_TYPE_P(value)) & 1) { + goto type_check_resource; + } + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + result = ((1 << IS_NULL) & opline->extended_value) != 0; + SAVE_OPLINE(); + ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception))) { + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + SAVE_OPLINE(); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); } else { - ZVAL_COPY(param, arg); + ZEND_VM_SMART_BRANCH(result, 0); } - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CAST_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_NAME_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { + uint32_t fetch_type; + zend_class_entry *called_scope, *scope; USE_OPLINE - zval *expr; - zval *result = EX_VAR(opline->result.var); - SAVE_OPLINE(); - expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - - switch (opline->extended_value) { - case IS_LONG: - ZVAL_LONG(result, zval_get_long(expr)); - break; - case IS_DOUBLE: - ZVAL_DOUBLE(result, zval_get_double(expr)); - break; - case IS_STRING: - ZVAL_STR(result, zval_get_string(expr)); - break; - default: - ZEND_ASSERT(opline->extended_value != _IS_BOOL && "Must use ZEND_BOOL instead"); - if (IS_TMP_VAR & (IS_VAR|IS_CV)) { - ZVAL_DEREF(expr); + if (IS_TMP_VAR != IS_UNUSED) { + SAVE_OPLINE(); + zval *op = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (UNEXPECTED(Z_TYPE_P(op) != IS_OBJECT)) { + ZVAL_DEREF(op); + if (Z_TYPE_P(op) != IS_OBJECT) { + zend_type_error("Cannot use \"::class\" on %s", zend_zval_value_name(op)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); } - /* If value is already of correct type, return it directly */ - if (Z_TYPE_P(expr) == opline->extended_value) { - ZVAL_COPY_VALUE(result, expr); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_TMP_VAR != IS_TMP_VAR) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); - } + } + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op)->name); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } + fetch_type = opline->op1.num; + scope = EX(func)->op_array.scope; + if (UNEXPECTED(scope == NULL)) { + SAVE_OPLINE(); + zend_throw_error(NULL, "Cannot use \"%s\" in the global scope", + fetch_type == ZEND_FETCH_CLASS_SELF ? "self" : + fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } - if (opline->extended_value == IS_ARRAY) { - zend_cast_zval_to_array(result, expr, IS_TMP_VAR); + switch (fetch_type) { + case ZEND_FETCH_CLASS_SELF: + ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->name); + break; + case ZEND_FETCH_CLASS_PARENT: + if (UNEXPECTED(scope->parent == NULL)) { + SAVE_OPLINE(); + zend_throw_error(NULL, + "Cannot use \"parent\" when current class scope has no parent"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->parent->name); + break; + case ZEND_FETCH_CLASS_STATIC: + if (Z_TYPE(EX(This)) == IS_OBJECT) { + called_scope = Z_OBJCE(EX(This)); } else { - ZEND_ASSERT(opline->extended_value == IS_OBJECT); - zend_cast_zval_to_object(result, expr, IS_TMP_VAR); + called_scope = Z_CE(EX(This)); } + ZVAL_STR_COPY(EX_VAR(opline->result.var), called_scope->name); + break; + EMPTY_SWITCH_DEFAULT_CASE() } - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_R_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *array_ptr, *result; + zval *op1, *op2; SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + div_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - array_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { - result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, array_ptr); - if (IS_TMP_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(array_ptr); - } - Z_FE_POS_P(result) = 0; - - - ZEND_VM_NEXT_OPCODE(); - } else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { - zend_object *zobj = Z_OBJ_P(array_ptr); - if (!zobj->ce->get_iterator) { - if (UNEXPECTED(zend_object_is_lazy(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (UNEXPECTED(EG(exception))) { - UNDEF_RESULT(); - - - HANDLE_EXCEPTION(); - } - } - HashTable *properties = zobj->properties; - if (properties) { - if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(properties); - } - properties = zobj->properties = zend_array_dup(properties); - } - } else { - properties = zobj->handlers->get_properties(zobj); - } - - result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, array_ptr); - if (IS_TMP_VAR != IS_TMP_VAR) { - Z_ADDREF_P(array_ptr); - } - - if (zend_hash_num_elements(properties) == 0) { - Z_FE_ITER_P(result) = (uint32_t) -1; - - - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); - } - - Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } else if (is_empty) { - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } - } else { - zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); - } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_RW_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *array_ptr, *array_ref; + zval *op1, *op2; SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + pow_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - array_ref = array_ptr = zend_get_bad_ptr(); - if (Z_ISREF_P(array_ref)) { - array_ptr = Z_REFVAL_P(array_ref); - } - } else { - array_ref = array_ptr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - } - if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { - if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - if (array_ptr == array_ref) { - ZVAL_NEW_REF(array_ref, array_ref); - array_ptr = Z_REFVAL_P(array_ref); - } - Z_ADDREF_P(array_ref); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); - } else { - array_ref = EX_VAR(opline->result.var); - ZVAL_NEW_REF(array_ref, array_ptr); - array_ptr = Z_REFVAL_P(array_ref); - } - if (IS_TMP_VAR == IS_CONST) { - ZVAL_ARR(array_ptr, zend_array_dup(Z_ARRVAL_P(array_ptr))); - } else { - SEPARATE_ARRAY(array_ptr); - } - Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(Z_ARRVAL_P(array_ptr), 0); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; - ZEND_VM_NEXT_OPCODE(); - } else if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { - if (!Z_OBJCE_P(array_ptr)->get_iterator) { - zend_object *zobj = Z_OBJ_P(array_ptr); - HashTable *properties; - if (UNEXPECTED(zend_object_is_lazy(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (UNEXPECTED(EG(exception))) { - UNDEF_RESULT(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); - HANDLE_EXCEPTION(); - } + if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); } - if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) { - if (array_ptr == array_ref) { - ZVAL_NEW_REF(array_ref, array_ref); - array_ptr = Z_REFVAL_P(array_ref); - } - Z_ADDREF_P(array_ref); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), array_ref); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { - array_ptr = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(array_ptr, array_ref); + ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - if (Z_OBJ_P(array_ptr)->properties - && UNEXPECTED(GC_REFCOUNT(Z_OBJ_P(array_ptr)->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(Z_OBJ_P(array_ptr)->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(Z_OBJ_P(array_ptr)->properties); - } - Z_OBJ_P(array_ptr)->properties = zend_array_dup(Z_OBJ_P(array_ptr)->properties); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); } + } else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); - properties = Z_OBJPROP_P(array_ptr); - if (zend_hash_num_elements(properties) == 0) { - Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t) -1; - - - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { + zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); } - - Z_FE_ITER_P(EX_VAR(opline->result.var)) = zend_hash_iterator_add(properties, 0); - - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - bool is_empty = zend_fe_reset_iterator(array_ptr, 1 OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } else if (is_empty) { - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else { - ZEND_VM_NEXT_OPCODE(); + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); } } + ZEND_VM_NEXT_OPCODE(); } else { - zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; + SAVE_OPLINE(); + + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = ZVAL_UNDEFINED_OP1(); + } + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = ZVAL_UNDEFINED_OP2(); + } + concat_function(EX_VAR(opline->result.var), op1, op2); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_END_SILENCE_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE + zval *op1, *op2; + bool result; - if (E_HAS_ONLY_FATAL_ERRORS(EG(error_reporting)) - && !E_HAS_ONLY_FATAL_ERRORS(Z_LVAL_P(EX_VAR(opline->op1.var)))) { - EG(error_reporting) = Z_LVAL_P(EX_VAR(opline->op1.var)); - } - ZEND_VM_NEXT_OPCODE(); + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + result = fast_is_identical_function(op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_SET_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_STRICT_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - zend_reference *ref = NULL; - bool ret; + zval *op1, *op2; + bool result; SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + result = fast_is_identical_function(op1, op2); - if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(value)) { - if (IS_TMP_VAR == IS_VAR) { - ref = Z_REF_P(value); - } - value = Z_REFVAL_P(value); - } - ret = i_zend_is_true(value); + ZEND_VM_SMART_BRANCH(result, 1); +} - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; - if (ret) { - zval *result = EX_VAR(opline->result.var); + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + result = fast_is_not_identical_function(op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_COPY_VALUE(result, value); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_TMP_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); - } else if (IS_TMP_VAR == IS_VAR && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COALESCE_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - zend_reference *ref = NULL; - - SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + zval *op1, *op2; + double d1, d2; - if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - if (IS_TMP_VAR & IS_VAR) { - ref = Z_REF_P(value); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; } - value = Z_REFVAL_P(value); - } - - if (Z_TYPE_P(value) > IS_NULL) { - zval *result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, value); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_TMP_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); - } else if ((IS_TMP_VAR & IS_VAR) && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - - if ((IS_TMP_VAR & IS_VAR) && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; + } } } - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_NULL_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *val, *result; - - val = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + zval *op1, *op2; + double d1, d2; - if (Z_TYPE_P(val) > IS_NULL) { - do { - if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { - val = Z_REFVAL_P(val); - if (Z_TYPE_P(val) <= IS_NULL) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - break; - } + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); } - ZEND_VM_NEXT_OPCODE(); - } while (0); - } - - result = EX_VAR(opline->result.var); - uint32_t short_circuiting_type = opline->extended_value & ZEND_SHORT_CIRCUITING_CHAIN_MASK; - if (EXPECTED(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { - ZVAL_NULL(result); - if (IS_TMP_VAR == IS_CV - && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF) - && (opline->extended_value & ZEND_JMP_NULL_BP_VAR_IS) == 0 - ) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; } } - } else if (short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { - ZVAL_FALSE(result); - } else { - ZEND_ASSERT(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); - ZVAL_TRUE(result); } - - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_SPEC_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *value; - zval *result = EX_VAR(opline->result.var); + zval *op1, *op2; + double d1, d2; - value = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - ZVAL_NULL(result); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} - if (IS_TMP_VAR == IS_CV) { - ZVAL_COPY_DEREF(result, value); - } else if (IS_TMP_VAR == IS_VAR) { - if (UNEXPECTED(Z_ISREF_P(value))) { - ZVAL_COPY_VALUE(result, Z_REFVAL_P(value)); - if (UNEXPECTED(Z_DELREF_P(value) == 0)) { - efree_size(Z_REF_P(value), sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); } - } else { - ZVAL_COPY_VALUE(result, value); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; } - } else { - ZVAL_COPY_VALUE(result, value); - if (IS_TMP_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) { - Z_ADDREF_P(result); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; } } } - ZEND_VM_NEXT_OPCODE(); + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - bool result; + double d1, d2; - SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; - ZEND_VM_SMART_BRANCH(result, 1); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + if (1 && IS_TMP_VAR == IS_CONST && IS_CONST == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_STRICT_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_identical_function(op1, op2); + compare_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_XOR_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; - bool result; SAVE_OPLINE(); op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_not_identical_function(op1, op2); + boolean_xor_function(EX_VAR(opline->result.var), op1, op2); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 1); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -76586,6 +71483,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_CONST == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + if (IS_TMP_VAR & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -76603,10 +71512,148 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG } ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { + if (IS_TMP_VAR == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + zend_string *op1_str, *op2_str, *str; + + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CONST == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + + if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CONST == IS_CONST || IS_CONST == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + } else if (IS_CONST != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_CONST & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + if (IS_TMP_VAR == IS_CONST) { + op1_str = Z_STR_P(op1); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + op1_str = zend_string_copy(Z_STR_P(op1)); + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + op1_str = zval_get_string_func(op1); + } + if (IS_CONST == IS_CONST) { + op2_str = Z_STR_P(op2); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + op2_str = zend_string_copy(Z_STR_P(op2)); + } else { + if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + } + op2_str = zval_get_string_func(op2); + } + do { + if (IS_TMP_VAR != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CONST == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + zend_string_release_ex(op1_str, 0); + break; + } + } + if (IS_CONST != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + zend_string_release_ex(op2_str, 0); + break; + } + } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + + ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR != IS_CONST) { + zend_string_release_ex(op1_str, 0); + } + if (IS_CONST != IS_CONST) { + zend_string_release_ex(op2_str, 0); + } + } while (0); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_ADD_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -76704,6 +71751,166 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_END_SPEC_TMP_ ZEND_VM_NEXT_OPCODE(); } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + zval *object; + zend_function *fbc; + zend_class_entry *called_scope; + zend_object *obj; + zend_execute_data *call; + uint32_t call_info; + + SAVE_OPLINE(); + + object = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + if (IS_CONST != IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } + + if (IS_CONST != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Method name must be a string"); + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } while (0); + } + + if (IS_TMP_VAR == IS_UNUSED) { + obj = Z_OBJ_P(object); + } else { + do { + if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + } else { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + if (IS_TMP_VAR & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } + break; + } + } + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + object = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_CONST != IS_CONST) { + + + } + HANDLE_EXCEPTION(); + } + } + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } + zend_invalid_method_call(object, function_name); + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } + } while (0); + } + + called_scope = obj->ce; + + if (IS_CONST == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else { + zend_object *orig_obj = obj; + + if (IS_CONST == IS_CONST) { + function_name = RT_CONSTANT(opline, opline->op2); + } + + /* First, locate the function. */ + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); + } + + + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + HANDLE_EXCEPTION(); + } + if (IS_CONST == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(obj == orig_obj)) { + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); + } + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + } + + if (IS_CONST != IS_CONST) { + + + } + + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; + } else if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR|IS_CV)) { + if (IS_TMP_VAR == IS_CV) { + GC_ADDREF(obj); /* For $this pointer */ + } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; + } + + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, obj); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAL_EX_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -76741,6 +71948,58 @@ send_val_by_ref:; ZEND_VM_NEXT_OPCODE(); } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = RT_CONSTANT(opline, opline->op2); + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +case_true: + ZEND_VM_SMART_BRANCH_TRUE(); + } else { +case_false: + ZEND_VM_SMART_BRANCH_FALSE(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto case_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +case_double: + if (d1 == d2) { + goto case_true; + } else { + goto case_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto case_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + + + if (result) { + goto case_true; + } else { + goto case_false; + } + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} + static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -76844,34 +72103,244 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ } else { - if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { - zend_cannot_add_element(); - zval_ptr_dtor_nogc(expr_ptr); + if (!zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr)) { + zend_cannot_add_element(); + zval_ptr_dtor_nogc(expr_ptr); + } + } + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zval *array; + uint32_t size; + USE_OPLINE + + SAVE_OPLINE(); + array = EX_VAR(opline->result.var); + if (IS_TMP_VAR != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_ARR(array, zend_new_array(0)); + ZEND_VM_NEXT_OPCODE(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + bool result; + zend_ulong hval; + zval *offset; + + SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + offset = RT_CONSTANT(opline, opline->op2); + + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + zval *value; + zend_string *str; + +isset_dim_obj_array: + ht = Z_ARRVAL_P(container); +isset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_CONST != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_prop; + } + } + value = zend_hash_find_ex(ht, str, IS_CONST == IS_CONST); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_prop: + value = zend_hash_index_find(ht, hval); + } else if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + offset = Z_REFVAL_P(offset); + goto isset_again; + } else { + value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); + if (UNEXPECTED(EG(exception))) { + result = 0; + goto isset_dim_obj_exit; + } + } + + if (!(opline->extended_value & ZEND_ISEMPTY)) { + /* > IS_NULL means not IS_UNDEF and not IS_NULL */ + result = value != NULL && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + + if (IS_TMP_VAR & (IS_CONST|IS_CV)) { + /* avoid exception check */ + + + ZEND_VM_SMART_BRANCH(result, 0); + } + } else { + result = (value == NULL || !i_zend_is_true(value)); + } + goto isset_dim_obj_exit; + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto isset_dim_obj_array; + } + } + + if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; + } + if (!(opline->extended_value & ZEND_ISEMPTY)) { + result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); + } else { + result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); + } + +isset_dim_obj_exit: + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + int result; + zval *offset; + zend_string *name, *tmp_name; + + SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + offset = RT_CONSTANT(opline, opline->op2); + + if (IS_TMP_VAR == IS_CONST || + (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } + } else { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } + } + + if (IS_CONST == IS_CONST) { + name = Z_STR_P(offset); + } else { + name = zval_try_get_tmp_string(offset, &tmp_name); + if (UNEXPECTED(!name)) { + result = 0; + goto isset_object_finish; + } + } + + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + + if (IS_CONST != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + +isset_object_finish: + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *key, *subject; + HashTable *ht; + bool result; + + SAVE_OPLINE(); + + key = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + subject = RT_CONSTANT(opline, opline->op2); + + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: + ht = Z_ARRVAL_P(subject); + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); + } else { + if ((IS_CONST & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } } + zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); + result = 0; } - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INSTANCEOF_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zval *array; - uint32_t size; USE_OPLINE + zval *expr; + bool result; SAVE_OPLINE(); - array = EX_VAR(opline->result.var); - if (IS_TMP_VAR != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + +try_instanceof: + if (Z_TYPE_P(expr) == IS_OBJECT) { + zend_class_entry *ce; + + if (IS_CONST == IS_CONST) { + ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (EXPECTED(ce)) { + CACHE_PTR(opline->extended_value, ce); + } + } + } else if (IS_CONST == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { + expr = Z_REFVAL_P(expr); + goto try_instanceof; } else { - ZVAL_ARR(array, zend_new_array(0)); - ZEND_VM_NEXT_OPCODE(); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + result = 0; } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); } static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_TMP_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -77040,35 +72509,560 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IN_ARRAY_SPEC_TMP_ HANDLE_EXCEPTION(); } } - result = zend_hash_find_known_hash(ht, ZSTR_EMPTY_ALLOC()); - ZEND_VM_SMART_BRANCH(result, 0); - } else { - zend_string *key; - zval key_tmp; - - if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - result = zend_hash_find(ht, Z_STR_P(op1)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 0); + result = zend_hash_find_known_hash(ht, ZSTR_EMPTY_ALLOC()); + ZEND_VM_SMART_BRANCH(result, 0); + } else { + zend_string *key; + zval key_tmp; + + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + result = zend_hash_find(ht, Z_STR_P(op1)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 0); + } + } + + SAVE_OPLINE(); + ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) { + ZVAL_STR(&key_tmp, key); + if (zend_compare(op1, &key_tmp) == 0) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(1, 1); + } + } ZEND_HASH_FOREACH_END(); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(0, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + div_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + pow_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + + if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + } else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { + zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = ZVAL_UNDEFINED_OP1(); + } + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = ZVAL_UNDEFINED_OP2(); + } + concat_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + result = fast_is_identical_function(op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_STRICT_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + result = fast_is_identical_function(op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + result = fast_is_not_identical_function(op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +is_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + } else { +is_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_equal_double: + if (d1 == d2) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (result) { + goto is_equal_true; + } else { + goto is_equal_false; + } + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_NONE(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_NONE(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPZ(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPZ(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_TMP_VAR == IS_CONST && IS_TMP_VAR == IS_CONST) { + /* pass */ + } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) != Z_LVAL_P(op2))) { +is_not_equal_true: + ZEND_VM_SMART_BRANCH_TRUE_JMPNZ(); + } else { +is_not_equal_false: + ZEND_VM_SMART_BRANCH_FALSE_JMPNZ(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto is_not_equal_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +is_not_equal_double: + if (d1 != d2) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto is_not_equal_double; } - - SAVE_OPLINE(); - ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) { - ZVAL_STR(&key_tmp, key); - if (zend_compare(op1, &key_tmp) == 0) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(1, 1); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op1); } - } ZEND_HASH_FOREACH_END(); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zval_ptr_dtor_str(op2); + } + if (!result) { + goto is_not_equal_true; + } else { + goto is_not_equal_false; + } + } } + ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + compare_function(EX_VAR(opline->result.var), op1, op2); zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(0, 1); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_XOR_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + boolean_xor_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 USE_OPLINE @@ -77080,14 +73074,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG } ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_TMP_VAR == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_TMP_VAR & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 USE_OPLINE @@ -77100,11 +73106,148 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG } ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_TMP_VAR == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + zend_string *op1_str, *op2_str, *str; + + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + + if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + } else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + if (IS_TMP_VAR == IS_CONST) { + op1_str = Z_STR_P(op1); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + op1_str = zend_string_copy(Z_STR_P(op1)); + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + op1_str = zval_get_string_func(op1); + } + if (IS_TMP_VAR == IS_CONST) { + op2_str = Z_STR_P(op2); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + op2_str = zend_string_copy(Z_STR_P(op2)); + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + } + op2_str = zval_get_string_func(op2); } + do { + if (IS_TMP_VAR != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + zend_string_release_ex(op1_str, 0); + break; + } + } + if (IS_TMP_VAR != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + zend_string_release_ex(op2_str, 0); + break; + } + } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + + ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR != IS_CONST) { + zend_string_release_ex(op1_str, 0); + } + if (IS_TMP_VAR != IS_CONST) { + zend_string_release_ex(op2_str, 0); + } + } while (0); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_ADD_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_string **rope; @@ -77112,23 +73255,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_ADD_SPEC_TMP_ /* op1 and result are the same */ rope = (zend_string**)EX_VAR(opline->op1.var); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); rope[opline->extended_value] = Z_STR_P(var); if (UNEXPECTED(Z_REFCOUNTED_P(var))) { Z_ADDREF_P(var); } } else { - var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { + if (IS_TMP_VAR == IS_CV) { rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); } else { rope[opline->extended_value] = Z_STR_P(var); } } else { SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); } rope[opline->extended_value] = zval_get_string_func(var); @@ -77139,7 +73282,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_ADD_SPEC_TMP_ ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_END_SPEC_TMP_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_END_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_string **rope; @@ -77147,23 +73290,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_END_SPEC_TMP_ uint32_t i; rope = (zend_string**)EX_VAR(opline->op1.var); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); rope[opline->extended_value] = Z_STR_P(var); if (UNEXPECTED(Z_REFCOUNTED_P(var))) { Z_ADDREF_P(var); } } else { - var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { + if (IS_TMP_VAR == IS_CV) { rope[opline->extended_value] = zend_string_copy(Z_STR_P(var)); } else { rope[opline->extended_value] = Z_STR_P(var); } } else { SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); } rope[opline->extended_value] = zval_get_string_func(var); @@ -77199,7 +73342,213 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_END_SPEC_TMP_ ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + zval *object; + zend_function *fbc; + zend_class_entry *called_scope; + zend_object *obj; + zend_execute_data *call; + uint32_t call_info; + + SAVE_OPLINE(); + + object = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + if (IS_TMP_VAR != IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + } + + if (IS_TMP_VAR != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Method name must be a string"); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } while (0); + } + + if (IS_TMP_VAR == IS_UNUSED) { + obj = Z_OBJ_P(object); + } else { + do { + if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + } else { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + if (IS_TMP_VAR & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } + break; + } + } + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + object = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_TMP_VAR != IS_CONST) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } + HANDLE_EXCEPTION(); + } + } + if (IS_TMP_VAR == IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + } + zend_invalid_method_call(object, function_name); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } + } while (0); + } + + called_scope = obj->ce; + + if (IS_TMP_VAR == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else { + zend_object *orig_obj = obj; + + if (IS_TMP_VAR == IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + } + + /* First, locate the function. */ + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + HANDLE_EXCEPTION(); + } + if (IS_TMP_VAR == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(obj == orig_obj)) { + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); + } + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + } + + if (IS_TMP_VAR != IS_CONST) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } + + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; + } else if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR|IS_CV)) { + if (IS_TMP_VAR == IS_CV) { + GC_ADDREF(obj); /* For $this pointer */ + } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; + } + + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, obj); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +case_true: + ZEND_VM_SMART_BRANCH_TRUE(); + } else { +case_false: + ZEND_VM_SMART_BRANCH_FALSE(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto case_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +case_double: + if (d1 == d2) { + goto case_true; + } else { + goto case_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto case_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + if (result) { + goto case_true; + } else { + goto case_false; + } + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *expr_ptr, new_expr; @@ -77239,15 +73588,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR != IS_UNUSED) { + zval *offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); zend_string *str; zend_ulong hval; add_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { if (ZEND_HANDLE_NUMERIC(str, hval)) { goto num_index; } @@ -77258,7 +73607,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ hval = Z_LVAL_P(offset); num_index: zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { offset = Z_REFVAL_P(offset); goto add_again; } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { @@ -77291,7 +73640,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ zend_use_resource_as_offset(offset); hval = Z_RES_HANDLE_P(offset); goto num_index; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + } else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); str = ZSTR_EMPTY_ALLOC(); goto str_index; @@ -77309,29 +73658,191 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zval *array; + uint32_t size; + USE_OPLINE + + SAVE_OPLINE(); + array = EX_VAR(opline->result.var); + if (IS_TMP_VAR != IS_UNUSED) { + size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; + ZVAL_ARR(array, zend_new_array(size)); + /* Explicitly initialize array as not-packed if flag is set */ + if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { + zend_hash_real_init_mixed(Z_ARRVAL_P(array)); + } + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + ZVAL_ARR(array, zend_new_array(0)); + ZEND_VM_NEXT_OPCODE(); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + bool result; + zend_ulong hval; + zval *offset; + + SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + zval *value; + zend_string *str; + +isset_dim_obj_array: + ht = Z_ARRVAL_P(container); +isset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_TMP_VAR != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_prop; + } + } + value = zend_hash_find_ex(ht, str, IS_TMP_VAR == IS_CONST); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_prop: + value = zend_hash_index_find(ht, hval); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + offset = Z_REFVAL_P(offset); + goto isset_again; + } else { + value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); + if (UNEXPECTED(EG(exception))) { + result = 0; + goto isset_dim_obj_exit; + } + } + + if (!(opline->extended_value & ZEND_ISEMPTY)) { + /* > IS_NULL means not IS_UNDEF and not IS_NULL */ + result = value != NULL && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + + if (IS_TMP_VAR & (IS_CONST|IS_CV)) { + /* avoid exception check */ + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_SMART_BRANCH(result, 0); + } + } else { + result = (value == NULL || !i_zend_is_true(value)); + } + goto isset_dim_obj_exit; + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto isset_dim_obj_array; + } + } + + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; + } + if (!(opline->extended_value & ZEND_ISEMPTY)) { + result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); + } else { + result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); + } + +isset_dim_obj_exit: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + int result; + zval *offset; + zend_string *name, *tmp_name; + + SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + if (IS_TMP_VAR == IS_CONST || + (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } + } else { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } + } + + if (IS_TMP_VAR == IS_CONST) { + name = Z_STR_P(offset); + } else { + name = zval_try_get_tmp_string(offset, &tmp_name); + if (UNEXPECTED(!name)) { + result = 0; + goto isset_object_finish; + } + } + + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + +isset_object_finish: + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - zval *array; - uint32_t size; USE_OPLINE + zval *key, *subject; + HashTable *ht; + bool result; + SAVE_OPLINE(); - array = EX_VAR(opline->result.var); - if (IS_TMP_VAR != IS_UNUSED) { - size = opline->extended_value >> ZEND_ARRAY_SIZE_SHIFT; - ZVAL_ARR(array, zend_new_array(size)); - /* Explicitly initialize array as not-packed if flag is set */ - if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { - zend_hash_real_init_mixed(Z_ARRVAL_P(array)); - } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + + key = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + subject = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: + ht = Z_ARRVAL_P(subject); + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); } else { - ZVAL_ARR(array, zend_new_array(0)); - ZEND_VM_NEXT_OPCODE(); + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } + } + zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); + result = 0; } + + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_TMP_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -77418,9 +73929,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_TMP_TMP } /* Set the new yielded key */ - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *key = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + if (IS_TMP_VAR != IS_UNUSED) { + zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { key = Z_REFVAL_P(key); } ZVAL_COPY(&generator->key, key); @@ -77453,64 +73964,86 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_TMP_TMP ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INSTANCEOF_SPEC_TMP_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1, *op2; + zval *expr; bool result; SAVE_OPLINE(); - op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); + expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + +try_instanceof: + if (Z_TYPE_P(expr) == IS_OBJECT) { + zend_class_entry *ce; + + if (IS_VAR == IS_CONST) { + ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (EXPECTED(ce)) { + CACHE_PTR(opline->extended_value, ce); + } + } + } else if (IS_VAR == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { + expr = Z_REFVAL_P(expr); + goto try_instanceof; + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + result = 0; + } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_STRICT_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_fetch_var_address_helper_SPEC_TMP_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX int type); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_R_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zval *op1, *op2; - bool result; + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_R)); +} - SAVE_OPLINE(); - op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_W_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_W)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_RW_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zval *op1, *op2; - bool result; + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_RW)); +} - SAVE_OPLINE(); - op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + int fetch_type = + (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ? + BP_VAR_W : BP_VAR_R; + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX fetch_type)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_STRICT_SPEC_TMP_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_UNSET_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { - USE_OPLINE - zval *op1, *op2; - bool result; + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_UNSET)); +} - SAVE_OPLINE(); - op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_IS_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_TMP_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX BP_VAR_IS)); } +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 @@ -77526,6 +74059,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_UNUSED == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + if (IS_TMP_VAR & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -77804,6 +74349,96 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_TM } } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + bool result; + zval *varname; + zend_string *name, *tmp_name; + HashTable *target_symbol_table; + + SAVE_OPLINE(); + varname = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + name = Z_STR_P(varname); + } else { + name = zval_get_tmp_string(varname, &tmp_name); + } + + target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); + value = zend_hash_find_ex(target_symbol_table, name, IS_TMP_VAR == IS_CONST); + + if (IS_TMP_VAR != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + if (!value) { + result = (opline->extended_value & ZEND_ISEMPTY); + } else { + if (Z_TYPE_P(value) == IS_INDIRECT) { + value = Z_INDIRECT_P(value); + } + if (!(opline->extended_value & ZEND_ISEMPTY)) { + if (Z_ISREF_P(value)) { + value = Z_REFVAL_P(value); + } + result = Z_TYPE_P(value) > IS_NULL; + } else { + result = !i_zend_is_true(value); + } + } + + ZEND_VM_SMART_BRANCH(result, true); +} + +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INSTANCEOF_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *expr; + bool result; + + SAVE_OPLINE(); + expr = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + +try_instanceof: + if (Z_TYPE_P(expr) == IS_OBJECT) { + zend_class_entry *ce; + + if (IS_UNUSED == IS_CONST) { + ce = CACHED_PTR(opline->extended_value); + if (UNEXPECTED(ce == NULL)) { + ce = zend_lookup_class_ex(Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(RT_CONSTANT(opline, opline->op2) + 1), ZEND_FETCH_CLASS_NO_AUTOLOAD); + if (EXPECTED(ce)) { + CACHE_PTR(opline->extended_value, ce); + } + } + } else if (IS_UNUSED == IS_UNUSED) { + ce = zend_fetch_class(NULL, opline->op2.num); + if (UNEXPECTED(ce == NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } + } else { + ce = Z_CE_P(EX_VAR(opline->op2.var)); + } + result = ce && instanceof_function(Z_OBJCE_P(expr), ce); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(expr) == IS_REFERENCE) { + expr = Z_REFVAL_P(expr); + goto try_instanceof; + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(expr) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + result = 0; + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} + static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -77926,6 +74561,119 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_TMP_UNU ZEND_VM_RETURN(); } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COUNT_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1; + zend_long count; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + while (1) { + if (Z_TYPE_P(op1) == IS_ARRAY) { + count = zend_hash_num_elements(Z_ARRVAL_P(op1)); + break; + } else if (Z_TYPE_P(op1) == IS_OBJECT) { + zend_object *zobj = Z_OBJ_P(op1); + + /* first, we check if the handler is defined */ + if (zobj->handlers->count_elements) { + if (SUCCESS == zobj->handlers->count_elements(zobj, &count)) { + break; + } + if (UNEXPECTED(EG(exception))) { + count = 0; + break; + } + } + + /* if not and the object implements Countable we call its count() method */ + if (zend_class_implements_interface(zobj->ce, zend_ce_countable)) { + zval retval; + + zend_function *count_fn = zend_hash_find_ptr(&zobj->ce->function_table, ZSTR_KNOWN(ZEND_STR_COUNT)); + zend_call_known_instance_method_with_0_params(count_fn, zobj, &retval); + count = zval_get_long(&retval); + zval_ptr_dtor(&retval); + break; + } + + /* If There's no handler and it doesn't implement Countable then emit a TypeError */ + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + continue; + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + count = 0; + zend_type_error("%s(): Argument #1 ($value) must be of type Countable|array, %s given", opline->extended_value ? "sizeof" : "count", zend_zval_value_name(op1)); + break; + } + + ZVAL_LONG(EX_VAR(opline->result.var), count); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_array *ht = Z_ARRVAL_P(_get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC)); + ZVAL_LONG(EX_VAR(opline->result.var), zend_hash_num_elements(ht)); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR) && !(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + SAVE_OPLINE(); + zend_array_destroy(ht); + if (EG(exception)) { + HANDLE_EXCEPTION(); + } + } + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GET_CLASS_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + if (IS_TMP_VAR == IS_UNUSED) { + SAVE_OPLINE(); + if (UNEXPECTED(!EX(func)->common.scope)) { + zend_throw_error(NULL, "get_class() without arguments must be called from within a class"); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + HANDLE_EXCEPTION(); + } else { + zend_error(E_DEPRECATED, "Calling get_class() without arguments is deprecated"); + ZVAL_STR_COPY(EX_VAR(opline->result.var), EX(func)->common.scope->name); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + ZEND_VM_NEXT_OPCODE(); + } + } else { + zval *op1; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + while (1) { + if (Z_TYPE_P(op1) == IS_OBJECT) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), Z_OBJCE_P(op1)->name); + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) != 0 && Z_TYPE_P(op1) == IS_REFERENCE) { + op1 = Z_REFVAL_P(op1); + continue; + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); + } + zend_type_error("get_class(): Argument #1 ($object) must be of type object, %s given", zend_zval_value_name(op1)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + } + break; + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +} + static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GET_TYPE_SPEC_TMP_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -77944,6 +74692,114 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GET_TYPE_SPEC_TMP_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + div_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + pow_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = EX_VAR(opline->op2.var); + + if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + + if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + if (UNEXPECTED(len > ZSTR_MAX_LEN - ZSTR_LEN(op2_str))) { + zend_error_noreturn(E_ERROR, "Integer overflow in memory allocation"); + } + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } + ZEND_VM_NEXT_OPCODE(); + } else { + SAVE_OPLINE(); + + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + op1 = ZVAL_UNDEFINED_OP1(); + } + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + op2 = ZVAL_UNDEFINED_OP2(); + } + concat_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + } +} + static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_STRICT_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -77959,40 +74815,205 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_STRICT_SPEC_T ZEND_VM_SMART_BRANCH(result, 1); } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + compare_function(EX_VAR(opline->result.var), op1, op2); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 USE_OPLINE #endif - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if (IS_CV == IS_UNUSED) { + ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + if (IS_TMP_VAR & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ +#if 0 + USE_OPLINE +#endif + + if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { + /* Behave like FETCH_OBJ_W */ + if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { + ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } + ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } else { + if (IS_TMP_VAR == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + } +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + zend_string *op1_str, *op2_str, *str; + + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = EX_VAR(opline->op2.var); + if ((IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && + (IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + zend_string *op1_str = Z_STR_P(op1); + zend_string *op2_str = Z_STR_P(op2); + zend_string *str; + uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); + + if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST || IS_CV == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + } + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + } else if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { + ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); + } else { + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else if (IS_TMP_VAR != IS_CONST && IS_TMP_VAR != IS_CV && + !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { + size_t len = ZSTR_LEN(op1_str); + + str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } else { + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); + GC_ADD_FLAGS(str, flags); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op1_str, 0); + } + if (IS_CV & (IS_TMP_VAR|IS_VAR)) { + zend_string_release_ex(op2_str, 0); + } + } + ZEND_VM_NEXT_OPCODE(); + } + + SAVE_OPLINE(); + if (IS_TMP_VAR == IS_CONST) { + op1_str = Z_STR_P(op1); + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + op1_str = zend_string_copy(Z_STR_P(op1)); + } else { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP1(); } - ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + op1_str = zval_get_string_func(op1); + } + if (IS_CV == IS_CONST) { + op2_str = Z_STR_P(op2); + } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + op2_str = zend_string_copy(Z_STR_P(op2)); } else { - if (IS_CV == IS_UNUSED) { - ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + op2_str = zval_get_string_func(op2); } -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ -#if 0 - USE_OPLINE -#endif + do { + if (IS_TMP_VAR != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { + if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { + GC_ADDREF(op2_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op2_str); + zend_string_release_ex(op1_str, 0); + break; + } + } + if (IS_CV != IS_CONST) { + if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + if (IS_TMP_VAR == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { + GC_ADDREF(op1_str); + } + } + ZVAL_STR(EX_VAR(opline->result.var), op1_str); + zend_string_release_ex(op2_str, 0); + break; + } + } + str = zend_string_alloc(ZSTR_LEN(op1_str) + ZSTR_LEN(op2_str), 0); + memcpy(ZSTR_VAL(str), ZSTR_VAL(op1_str), ZSTR_LEN(op1_str)); + memcpy(ZSTR_VAL(str) + ZSTR_LEN(op1_str), ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); - if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) { - /* Behave like FETCH_OBJ_W */ - if ((IS_TMP_VAR & (IS_CONST|IS_TMP_VAR))) { - ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZSTR_COPY_CONCAT_PROPERTIES_BOTH(str, op1_str, op2_str); + ZVAL_NEW_STR(EX_VAR(opline->result.var), str); + if (IS_TMP_VAR != IS_CONST) { + zend_string_release_ex(op1_str, 0); } - ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } + if (IS_CV != IS_CONST) { + zend_string_release_ex(op2_str, 0); + } + } while (0); + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_ADD_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -78092,6 +75113,218 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_END_SPEC_TMP_ ZEND_VM_NEXT_OPCODE(); } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *function_name; + zval *object; + zend_function *fbc; + zend_class_entry *called_scope; + zend_object *obj; + zend_execute_data *call; + uint32_t call_info; + + SAVE_OPLINE(); + + object = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + + if (IS_CV != IS_CONST) { + function_name = EX_VAR(opline->op2.var); + } + + if (IS_CV != IS_CONST && + UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { + do { + if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + function_name = Z_REFVAL_P(function_name); + if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + break; + } + } else if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + ZVAL_UNDEFINED_OP2(); + if (UNEXPECTED(EG(exception) != NULL)) { + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } + } + zend_throw_error(NULL, "Method name must be a string"); + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } while (0); + } + + if (IS_TMP_VAR == IS_UNUSED) { + obj = Z_OBJ_P(object); + } else { + do { + if (IS_TMP_VAR != IS_CONST && EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + } else { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(object))) { + zend_reference *ref = Z_REF_P(object); + + object = &ref->val; + if (EXPECTED(Z_TYPE_P(object) == IS_OBJECT)) { + obj = Z_OBJ_P(object); + if (IS_TMP_VAR & IS_VAR) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_ADDREF_P(object); + } + } + break; + } + } + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { + object = ZVAL_UNDEFINED_OP1(); + if (UNEXPECTED(EG(exception) != NULL)) { + if (IS_CV != IS_CONST) { + + + } + HANDLE_EXCEPTION(); + } + } + if (IS_CV == IS_CONST) { + function_name = EX_VAR(opline->op2.var); + } + zend_invalid_method_call(object, function_name); + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + HANDLE_EXCEPTION(); + } + } while (0); + } + + called_scope = obj->ce; + + if (IS_CV == IS_CONST && + EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { + fbc = CACHED_PTR(opline->result.num + sizeof(void*)); + } else { + zend_object *orig_obj = obj; + + if (IS_CV == IS_CONST) { + function_name = EX_VAR(opline->op2.var); + } + + /* First, locate the function. */ + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + if (UNEXPECTED(fbc == NULL)) { + if (EXPECTED(!EG(exception))) { + zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); + } + + + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + HANDLE_EXCEPTION(); + } + if (IS_CV == IS_CONST && + EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && + EXPECTED(obj == orig_obj)) { + CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); + } + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(obj != orig_obj)) { + GC_ADDREF(obj); /* For $this pointer */ + if (GC_DELREF(orig_obj) == 0) { + zend_objects_store_del(orig_obj); + } + } + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { + init_func_run_time_cache(&fbc->op_array); + } + } + + if (IS_CV != IS_CONST) { + + + } + + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0)) { + if ((IS_TMP_VAR & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(obj) == 0) { + zend_objects_store_del(obj); + if (UNEXPECTED(EG(exception))) { + HANDLE_EXCEPTION(); + } + } + /* call static method */ + obj = (zend_object*)called_scope; + call_info = ZEND_CALL_NESTED_FUNCTION; + } else if (IS_TMP_VAR & (IS_VAR|IS_TMP_VAR|IS_CV)) { + if (IS_TMP_VAR == IS_CV) { + GC_ADDREF(obj); /* For $this pointer */ + } + /* CV may be changed indirectly (e.g. when it's a reference) */ + call_info = ZEND_CALL_NESTED_FUNCTION | ZEND_CALL_HAS_THIS | ZEND_CALL_RELEASE_THIS; + } + + call = zend_vm_stack_push_call_frame(call_info, + fbc, opline->extended_value, obj); + call->prev_execute_data = EX(call); + EX(call) = call; + + ZEND_VM_NEXT_OPCODE(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + double d1, d2; + + op1 = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + op2 = EX_VAR(opline->op2.var); + if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + if (EXPECTED(Z_LVAL_P(op1) == Z_LVAL_P(op2))) { +case_true: + ZEND_VM_SMART_BRANCH_TRUE(); + } else { +case_false: + ZEND_VM_SMART_BRANCH_FALSE(); + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = (double)Z_LVAL_P(op1); + d2 = Z_DVAL_P(op2); + goto case_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) { + d1 = Z_DVAL_P(op1); + d2 = Z_DVAL_P(op2); +case_double: + if (d1 == d2) { + goto case_true; + } else { + goto case_false; + } + } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { + d1 = Z_DVAL_P(op1); + d2 = (double)Z_LVAL_P(op2); + goto case_double; + } + } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { + if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { + bool result = zend_fast_equal_strings(Z_STR_P(op1), Z_STR_P(op2)); + + + if (result) { + goto case_true; + } else { + goto case_false; + } + } + } + ZEND_VM_DISPATCH_TO_HELPER(zend_case_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); +} + static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -78225,6 +75458,171 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_TM } } +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + bool result; + zend_ulong hval; + zval *offset; + + SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + offset = EX_VAR(opline->op2.var); + + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + HashTable *ht; + zval *value; + zend_string *str; + +isset_dim_obj_array: + ht = Z_ARRVAL_P(container); +isset_again: + if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { + str = Z_STR_P(offset); + if (IS_CV != IS_CONST) { + if (ZEND_HANDLE_NUMERIC(str, hval)) { + goto num_index_prop; + } + } + value = zend_hash_find_ex(ht, str, IS_CV == IS_CONST); + } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { + hval = Z_LVAL_P(offset); +num_index_prop: + value = zend_hash_index_find(ht, hval); + } else if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + offset = Z_REFVAL_P(offset); + goto isset_again; + } else { + value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC); + if (UNEXPECTED(EG(exception))) { + result = 0; + goto isset_dim_obj_exit; + } + } + + if (!(opline->extended_value & ZEND_ISEMPTY)) { + /* > IS_NULL means not IS_UNDEF and not IS_NULL */ + result = value != NULL && Z_TYPE_P(value) > IS_NULL && + (!Z_ISREF_P(value) || Z_TYPE_P(Z_REFVAL_P(value)) != IS_NULL); + + if (IS_TMP_VAR & (IS_CONST|IS_CV)) { + /* avoid exception check */ + + + ZEND_VM_SMART_BRANCH(result, 0); + } + } else { + result = (value == NULL || !i_zend_is_true(value)); + } + goto isset_dim_obj_exit; + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(container))) { + container = Z_REFVAL_P(container); + if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { + goto isset_dim_obj_array; + } + } + + if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; + } + if (!(opline->extended_value & ZEND_ISEMPTY)) { + result = zend_isset_dim_slow(container, offset EXECUTE_DATA_CC); + } else { + result = zend_isempty_dim_slow(container, offset EXECUTE_DATA_CC); + } + +isset_dim_obj_exit: + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *container; + int result; + zval *offset; + zend_string *name, *tmp_name; + + SAVE_OPLINE(); + container = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); + + if (IS_TMP_VAR == IS_CONST || + (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + container = Z_REFVAL_P(container); + if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } + } else { + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; + } + } + + if (IS_CV == IS_CONST) { + name = Z_STR_P(offset); + } else { + name = zval_try_get_tmp_string(offset, &tmp_name); + if (UNEXPECTED(!name)) { + result = 0; + goto isset_object_finish; + } + } + + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + + if (IS_CV != IS_CONST) { + zend_tmp_string_release(tmp_name); + } + +isset_object_finish: + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + + zval *key, *subject; + HashTable *ht; + bool result; + + SAVE_OPLINE(); + + key = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); + subject = EX_VAR(opline->op2.var); + + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { +array_key_exists_array: + ht = Z_ARRVAL_P(subject); + result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); + } else { + if ((IS_CV & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + subject = Z_REFVAL_P(subject); + if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { + goto array_key_exists_array; + } + } + zend_array_key_exists_error(subject, key OPLINE_CC EXECUTE_DATA_CC); + result = 0; + } + + + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} + static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_TMP_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -78614,88 +76012,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_D ZEND_VM_TAIL_CALL(zend_post_dec_helper_SPEC_VAR_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *retval_ptr; - zval *return_value; - - - retval_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - return_value = EX(return_value); - - - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) { - SAVE_OPLINE(); - retval_ptr = ZVAL_UNDEFINED_OP1(); - if (return_value) { - ZVAL_NULL(return_value); - } - } else if (!return_value) { - if (IS_VAR & (IS_VAR|IS_TMP_VAR)) { - if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) { - SAVE_OPLINE(); - rc_dtor_func(Z_COUNTED_P(retval_ptr)); - } - } - } else { - if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) { - Z_ADDREF_P(return_value); - } - } - } else if (IS_VAR == IS_CV) { - do { - if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { - zend_refcounted *ref = Z_COUNTED_P(retval_ptr); - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (GC_MAY_LEAK(ref)) { - SAVE_OPLINE(); - gc_possible_root(ref); - } - ZVAL_NULL(retval_ptr); - break; - } else { - Z_ADDREF_P(retval_ptr); - } - } else { - retval_ptr = Z_REFVAL_P(retval_ptr); - if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } - } - } - ZVAL_COPY_VALUE(return_value, retval_ptr); - } while (0); - } else /* if (IS_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(retval_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(retval_ptr); - - retval_ptr = Z_REFVAL_P(retval_ptr); - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } - } else { - ZVAL_COPY_VALUE(return_value, retval_ptr); - } - } - } - - - - - - - ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); -} - static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_BY_REF_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -78761,6 +76077,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_BY_REF_SPEC + // FIXME: Don't create the ref in the first place? + zend_return_unwrap_ref(execute_data, return_value); + ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); } @@ -78810,153 +76129,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GENERATOR_RETURN_S ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_USER_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *arg, *param; - - SAVE_OPLINE(); - - arg = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - param = ZEND_CALL_VAR(EX(call), opline->result.var); - if (UNEXPECTED(ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num))) { - zend_param_must_be_ref(EX(call)->func, opline->op2.num); - Z_TRY_ADDREF_P(arg); - ZVAL_NEW_REF(param, arg); - } else { - ZVAL_COPY(param, arg); - } - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CAST_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *expr; - zval *result = EX_VAR(opline->result.var); - - SAVE_OPLINE(); - expr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - switch (opline->extended_value) { - case IS_LONG: - ZVAL_LONG(result, zval_get_long(expr)); - break; - case IS_DOUBLE: - ZVAL_DOUBLE(result, zval_get_double(expr)); - break; - case IS_STRING: - ZVAL_STR(result, zval_get_string(expr)); - break; - default: - ZEND_ASSERT(opline->extended_value != _IS_BOOL && "Must use ZEND_BOOL instead"); - if (IS_VAR & (IS_VAR|IS_CV)) { - ZVAL_DEREF(expr); - } - /* If value is already of correct type, return it directly */ - if (Z_TYPE_P(expr) == opline->extended_value) { - ZVAL_COPY_VALUE(result, expr); - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); - } - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } - - if (opline->extended_value == IS_ARRAY) { - zend_cast_zval_to_array(result, expr, IS_VAR); - } else { - ZEND_ASSERT(opline->extended_value == IS_OBJECT); - zend_cast_zval_to_object(result, expr, IS_VAR); - } - } - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_R_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *array_ptr, *result; - - SAVE_OPLINE(); - - array_ptr = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(array_ptr) == IS_ARRAY)) { - result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, array_ptr); - if (IS_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(array_ptr); - } - Z_FE_POS_P(result) = 0; - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); - } else if (IS_VAR != IS_CONST && EXPECTED(Z_TYPE_P(array_ptr) == IS_OBJECT)) { - zend_object *zobj = Z_OBJ_P(array_ptr); - if (!zobj->ce->get_iterator) { - if (UNEXPECTED(zend_object_is_lazy(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (UNEXPECTED(EG(exception))) { - UNDEF_RESULT(); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - HANDLE_EXCEPTION(); - } - } - HashTable *properties = zobj->properties; - if (properties) { - if (UNEXPECTED(GC_REFCOUNT(properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(properties); - } - properties = zobj->properties = zend_array_dup(properties); - } - } else { - properties = zobj->handlers->get_properties(zobj); - } - - result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, array_ptr); - if (IS_VAR != IS_TMP_VAR) { - Z_ADDREF_P(array_ptr); - } - - if (zend_hash_num_elements(properties) == 0) { - Z_FE_ITER_P(result) = (uint32_t) -1; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); - } - - Z_FE_ITER_P(result) = zend_hash_iterator_add(properties, 0); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - bool is_empty = zend_fe_reset_iterator(array_ptr, 0 OPLINE_CC EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - if (UNEXPECTED(EG(exception))) { - HANDLE_EXCEPTION(); - } else if (is_empty) { - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } else { - ZEND_VM_NEXT_OPCODE(); - } - } - } else { - zend_error(E_WARNING, "foreach() argument must be of type array|object, %s given", zend_zval_value_name(array_ptr)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - Z_FE_ITER_P(EX_VAR(opline->result.var)) = (uint32_t)-1; - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2)); - } -} - static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_RW_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -79056,86 +76228,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_RESET_RW_SPEC_V } } -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_FETCH_R_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *array; - zval *value; - uint32_t value_type; - HashTable *fe_ht; - HashPosition pos; - - array = EX_VAR(opline->op1.var); - if (UNEXPECTED(Z_TYPE_P(array) != IS_ARRAY)) { - ZEND_VM_TAIL_CALL(zend_fe_fetch_object_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); - } - fe_ht = Z_ARRVAL_P(array); - pos = Z_FE_POS_P(array); - if (HT_IS_PACKED(fe_ht)) { - value = fe_ht->arPacked + pos; - while (1) { - if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { - /* reached end of iteration */ - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } - value_type = Z_TYPE_INFO_P(value); - ZEND_ASSERT(value_type != IS_INDIRECT); - if (EXPECTED(value_type != IS_UNDEF)) { - break; - } - pos++; - value++; - } - Z_FE_POS_P(array) = pos + 1; - if (RETURN_VALUE_USED(opline)) { - ZVAL_LONG(EX_VAR(opline->result.var), pos); - } - } else { - Bucket *p; - - p = fe_ht->arData + pos; - while (1) { - if (UNEXPECTED(pos >= fe_ht->nNumUsed)) { - /* reached end of iteration */ - ZEND_VM_SET_RELATIVE_OPCODE(opline, opline->extended_value); - ZEND_VM_CONTINUE(); - } - pos++; - value = &p->val; - value_type = Z_TYPE_INFO_P(value); - ZEND_ASSERT(value_type != IS_INDIRECT); - if (EXPECTED(value_type != IS_UNDEF)) { - break; - } - p++; - } - Z_FE_POS_P(array) = pos; - if (RETURN_VALUE_USED(opline)) { - if (!p->key) { - ZVAL_LONG(EX_VAR(opline->result.var), p->h); - } else { - ZVAL_STR_COPY(EX_VAR(opline->result.var), p->key); - } - } - } - if (EXPECTED(opline->op2_type == IS_CV)) { - zval *variable_ptr = EX_VAR(opline->op2.var); - SAVE_OPLINE(); - zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else { - zval *res = EX_VAR(opline->op2.var); - zend_refcounted *gc = Z_COUNTED_P(value); - - ZVAL_COPY_VALUE_EX(res, value, gc, value_type); - if (Z_TYPE_INFO_REFCOUNTED(value_type)) { - GC_ADDREF(gc); - } - ZEND_VM_NEXT_OPCODE(); - } -} - static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_FETCH_RW_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -79339,138 +76431,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_FETCH_RW_SPEC_V ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_SET_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zend_reference *ref = NULL; - bool ret; - - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - ref = Z_REF_P(value); - } - value = Z_REFVAL_P(value); - } - - ret = i_zend_is_true(value); - - if (UNEXPECTED(EG(exception))) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - HANDLE_EXCEPTION(); - } - - if (ret) { - zval *result = EX_VAR(opline->result.var); - - ZVAL_COPY_VALUE(result, value); - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); - } else if (IS_VAR == IS_VAR && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_COALESCE_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zend_reference *ref = NULL; - - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if ((IS_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(value)) { - if (IS_VAR & IS_VAR) { - ref = Z_REF_P(value); - } - value = Z_REFVAL_P(value); - } - - if (Z_TYPE_P(value) > IS_NULL) { - zval *result = EX_VAR(opline->result.var); - ZVAL_COPY_VALUE(result, value); - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(result))) Z_ADDREF_P(result); - } else if (IS_VAR == IS_CV) { - if (Z_OPT_REFCOUNTED_P(result)) Z_ADDREF_P(result); - } else if ((IS_VAR & IS_VAR) && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); - } - } - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); - } - - if ((IS_VAR & IS_VAR) && ref) { - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } - } - ZEND_VM_NEXT_OPCODE(); -} - -static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_JMP_NULL_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *val, *result; - - val = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (Z_TYPE_P(val) > IS_NULL) { - do { - if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_TYPE_P(val) == IS_REFERENCE) { - val = Z_REFVAL_P(val); - if (Z_TYPE_P(val) <= IS_NULL) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - break; - } - } - ZEND_VM_NEXT_OPCODE(); - } while (0); - } - - result = EX_VAR(opline->result.var); - uint32_t short_circuiting_type = opline->extended_value & ZEND_SHORT_CIRCUITING_CHAIN_MASK; - if (EXPECTED(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EXPR)) { - ZVAL_NULL(result); - if (IS_VAR == IS_CV - && UNEXPECTED(Z_TYPE_P(val) == IS_UNDEF) - && (opline->extended_value & ZEND_JMP_NULL_BP_VAR_IS) == 0 - ) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - } else if (short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_ISSET) { - ZVAL_FALSE(result); - } else { - ZEND_ASSERT(short_circuiting_type == ZEND_SHORT_CIRCUITING_CHAIN_EMPTY); - ZVAL_TRUE(result); - } - - ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op2), 0); -} - static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_QM_ASSIGN_SPEC_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -79526,53 +76486,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_V ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_STRICT_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_identical_function(op1, op2); - - - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = RT_CONSTANT(opline, opline->op2); - result = fast_is_not_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - - - ZEND_VM_SMART_BRANCH(result, 1); -} - static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -79666,7 +76579,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -79974,6 +76887,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_CONST == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + if (IS_VAR & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -80047,6 +76972,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { + if (IS_VAR == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -80248,7 +77185,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -80403,162 +77340,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_obj has two opcodes! */ - 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -80715,7 +77497,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -81028,160 +77810,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_CONST == IS_UNUSED) { - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CONST == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = RT_CONSTANT(opline, opline->op2); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = RT_CONSTANT(opline, opline->op2); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = RT_CONSTANT(opline, opline->op2); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_CONST != IS_UNUSED) { - - - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -81435,7 +78063,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -81474,7 +78102,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -82450,78 +79078,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_VAR_CON ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IN_ARRAY_SPEC_VAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1; - HashTable *ht = Z_ARRVAL_P(RT_CONSTANT(opline, opline->op2)); - zval *result; - - op1 = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - result = zend_hash_find_ex(ht, Z_STR_P(op1), IS_VAR == IS_CONST); - if (IS_VAR & (IS_TMP_VAR|IS_VAR)) { - zval_ptr_dtor_str(op1); - } - ZEND_VM_SMART_BRANCH(result, 0); - } - - if (opline->extended_value) { - if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - ZEND_VM_SMART_BRANCH(result, 0); - } - SAVE_OPLINE(); - if ((IS_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - result = zend_hash_find(ht, Z_STR_P(op1)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 0); - } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { - result = zend_hash_index_find(ht, Z_LVAL_P(op1)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 0); - } - } else if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - ZVAL_UNDEFINED_OP1(); - } - } else if (Z_TYPE_P(op1) <= IS_FALSE) { - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { - SAVE_OPLINE(); - ZVAL_UNDEFINED_OP1(); - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - } - result = zend_hash_find_known_hash(ht, ZSTR_EMPTY_ALLOC()); - ZEND_VM_SMART_BRANCH(result, 0); - } else { - zend_string *key; - zval key_tmp; - - if ((IS_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(op1) == IS_REFERENCE) { - op1 = Z_REFVAL_P(op1); - if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) { - result = zend_hash_find(ht, Z_STR_P(op1)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(result, 0); - } - } - - SAVE_OPLINE(); - ZEND_HASH_MAP_FOREACH_STR_KEY(ht, key) { - ZVAL_STR(&key_tmp, key); - if (zend_compare(op1, &key_tmp) == 0) { - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(1, 1); - } - } ZEND_HASH_FOREACH_END(); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_SMART_BRANCH(0, 1); -} - static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_class_entry *ce, *scope; @@ -82655,7 +79211,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_CONSTA ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object; @@ -82670,7 +79226,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); do { value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); @@ -82691,7 +79247,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC assign_op_object: /* here we are sure we are dealing with an object */ zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(property); } else { name = zval_try_get_tmp_string(property, &tmp_name); @@ -82700,7 +79256,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -82735,7 +79291,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC } else { zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } } while (0); @@ -82747,8 +79303,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *var_ptr; @@ -82763,15 +79319,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC SEPARATE_ARRAY(container); ht = Z_ARRVAL_P(container); assign_dim_op_new_array: - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_UNUSED) { var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { zend_cannot_add_element(); goto assign_dim_op_ret_null; } } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); } else { var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); @@ -82784,7 +79340,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); do { - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { zend_reference *ref = Z_REF_P(var_ptr); var_ptr = Z_REFVAL_P(var_ptr); if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { @@ -82810,8 +79366,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(container); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); @@ -82834,7 +79390,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC } goto assign_dim_op_new_array; } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); assign_dim_op_ret_null: FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -82849,14 +79405,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OP_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *var_ptr; zval *value; SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); var_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); do { @@ -82880,7 +79436,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OP_SPEC_VAR ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object; @@ -82894,7 +79450,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_V SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -82913,7 +79469,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_V pre_incdec_object: /* here we are sure we are dealing with an object */ zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(property); } else { name = zval_try_get_tmp_string(property, &tmp_name); @@ -82922,7 +79478,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_V break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -82935,7 +79491,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_V } else { zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } } while (0); @@ -82945,7 +79501,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_V ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object; @@ -82959,7 +79515,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_ SAVE_OPLINE(); object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -82978,7 +79534,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_ post_incdec_object: /* here we are sure we are dealing with an object */ zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(property); } else { name = zval_try_get_tmp_string(property, &tmp_name); @@ -82987,7 +79543,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_ break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -82998,7 +79554,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_ } else { zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } } while (0); @@ -83008,14 +79564,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_W_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_W(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_dimension_address_W(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -83023,14 +79579,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_W_SPEC_V ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_RW(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_dimension_address_RW(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -83038,7 +79594,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_RW_SPEC_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 USE_OPLINE @@ -83048,23 +79604,35 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_TMP_VAR == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_VAR & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - zend_fetch_dimension_address_UNSET(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_dimension_address_UNSET(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -83072,7 +79640,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_UNSET_SP ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *property, *container, *result; @@ -83080,11 +79648,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_V SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); zend_fetch_property_address( - result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), - (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), + result, container, IS_VAR, property, IS_TMP_VAR, + ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_VAR == IS_VAR) { @@ -83093,16 +79661,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_V ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *property, *container, *result; SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -83110,7 +79678,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 USE_OPLINE @@ -83121,22 +79689,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_VAR == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container, *property, *result; SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -83144,30 +79724,30 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SP ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_LIST_W_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container, *dim; SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if (IS_VAR == IS_VAR && Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT && UNEXPECTED(!Z_ISREF_P(container)) ) { zend_error(E_NOTICE, "Attempting to set reference to non referenceable value"); - zend_fetch_dimension_address_LIST_r(container, dim, (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_dimension_address_LIST_r(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); } else { - zend_fetch_dimension_address_W(container, dim, (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_dimension_address_W(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); } zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object, *value, tmp; @@ -83184,14 +79764,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA object = Z_REFVAL_P(object); goto assign_object; } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); value = &EG(uninitialized_zval); goto free_and_exit_assign_obj; } assign_object: zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -83217,7 +79797,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA } } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { zobj = zend_lazy_object_init(zobj); if (!zobj) { @@ -83285,9 +79865,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA /* Fall through to write_property for hooks. */ } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { @@ -83300,9 +79880,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -83322,8 +79902,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object, *value, tmp; @@ -83340,14 +79920,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA object = Z_REFVAL_P(object); goto assign_object; } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); value = &EG(uninitialized_zval); goto free_and_exit_assign_obj; } assign_object: zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -83373,7 +79953,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA } } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { zobj = zend_lazy_object_init(zobj); if (!zobj) { @@ -83441,9 +80021,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA /* Fall through to write_property for hooks. */ } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); @@ -83455,163 +80035,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -83630,8 +80056,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object, *value, tmp; @@ -83648,14 +80074,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA object = Z_REFVAL_P(object); goto assign_object; } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); value = &EG(uninitialized_zval); goto free_and_exit_assign_obj; } assign_object: zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -83681,7 +80107,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA } } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { zobj = zend_lazy_object_init(zobj); if (!zobj) { @@ -83749,9 +80175,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA /* Fall through to write_property for hooks. */ } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { @@ -83764,9 +80190,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -83786,8 +80212,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object_ptr, *orig_object_ptr; @@ -83802,7 +80228,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_TMP_VAR == IS_UNUSED) { value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { HashTable *ht = Z_ARRVAL_P(object_ptr); @@ -83840,8 +80266,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA } } } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); @@ -83869,10 +80295,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_object *obj = Z_OBJ_P(object_ptr); GC_ADDREF(obj); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + } else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } @@ -83890,13 +80316,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_TMP_VAR == IS_UNUSED) { zend_use_new_element_for_string(); UNDEF_RESULT(); } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); value = RT_CONSTANT((opline+1), (opline+1)->op1); zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); @@ -83906,7 +80332,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); UNDEF_RESULT(); @@ -83927,7 +80353,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA } } else { zend_use_scalar_as_array(); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); assign_dim_error: @@ -83936,7 +80362,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA } } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + if (IS_TMP_VAR != IS_UNUSED) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); @@ -83944,7 +80370,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object_ptr, *orig_object_ptr; @@ -83959,7 +80385,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_TMP_VAR == IS_UNUSED) { value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { HashTable *ht = Z_ARRVAL_P(object_ptr); @@ -83997,8 +80423,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA } } } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); @@ -84026,170 +80452,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_object *obj = Z_OBJ_P(object_ptr); GC_ADDREF(obj); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + } else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_VAR & (IS_CV|IS_VAR)) { + } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } @@ -84200,13 +80473,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_TMP_VAR == IS_UNUSED) { zend_use_new_element_for_string(); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); } @@ -84214,7 +80487,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); } else { @@ -84234,7 +80507,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA } } else { zend_use_scalar_as_array(); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); assign_dim_error: zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -84242,7 +80515,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA } } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + if (IS_TMP_VAR != IS_UNUSED) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); @@ -84250,7 +80523,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object_ptr, *orig_object_ptr; @@ -84265,7 +80538,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_TMP_VAR == IS_UNUSED) { value = EX_VAR((opline+1)->op1.var); if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { HashTable *ht = Z_ARRVAL_P(object_ptr); @@ -84303,8 +80576,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA } } } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); @@ -84332,10 +80605,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_object *obj = Z_OBJ_P(object_ptr); GC_ADDREF(obj); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + } else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } @@ -84353,13 +80626,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_TMP_VAR == IS_UNUSED) { zend_use_new_element_for_string(); UNDEF_RESULT(); } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); value = EX_VAR((opline+1)->op1.var); zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); @@ -84369,7 +80642,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); UNDEF_RESULT(); @@ -84390,7 +80663,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA } } else { zend_use_scalar_as_array(); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); assign_dim_error: @@ -84399,7 +80672,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA } } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + if (IS_TMP_VAR != IS_UNUSED) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); @@ -84407,7 +80680,65 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + zval *variable_ptr; + + SAVE_OPLINE(); + value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + if (0 || UNEXPECTED(0)) { + zend_refcounted *garbage = NULL; + + value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(0)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES()); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* zend_assign_to_variable() always takes care of op2, never free it! */ + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *value; + zval *variable_ptr; + + SAVE_OPLINE(); + value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + if (0 || UNEXPECTED(1)) { + zend_refcounted *garbage = NULL; + + value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(1)) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES()); + } + zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); + /* zend_assign_to_variable() always takes care of op2, never free it! */ + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *property, *container, *value_ptr; @@ -84415,26 +80746,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); if (1) { if (IS_VAR == IS_UNUSED) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } } else { - zend_assign_to_property_reference(container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_property_reference(container, IS_VAR, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); @@ -84443,8 +80774,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *property, *container, *value_ptr; @@ -84452,26 +80783,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); if (1) { if (IS_VAR == IS_UNUSED) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } } else { - zend_assign_to_property_reference(container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_property_reference(container, IS_VAR, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); } zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); @@ -84481,8 +80812,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; @@ -84502,7 +80833,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { CACHE_PTR(opline->result.num, ce); } } @@ -84517,24 +80848,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD } if (IS_VAR == IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && + IS_TMP_VAR == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_VAR != IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && + IS_TMP_VAR == IS_CONST && EXPECTED(CACHED_PTR(opline->result.num) == ce)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + } else if (IS_TMP_VAR != IS_UNUSED) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR != IS_CONST) { if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + if (IS_TMP_VAR & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -84550,7 +80881,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { @@ -84559,7 +80890,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_TMP_VAR == IS_CONST && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); @@ -84567,7 +80898,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } } else { @@ -84615,7 +80946,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *expr_ptr, new_expr; @@ -84655,15 +80986,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR != IS_UNUSED) { + zval *offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); zend_string *str; zend_ulong hval; add_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { if (ZEND_HANDLE_NUMERIC(str, hval)) { goto num_index; } @@ -84674,7 +81005,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ hval = Z_LVAL_P(offset); num_index: zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { offset = Z_REFVAL_P(offset); goto add_again; } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { @@ -84707,7 +81038,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ zend_use_resource_as_offset(offset); hval = Z_RES_HANDLE_P(offset); goto num_index; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + } else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); str = ZSTR_EMPTY_ALLOC(); goto str_index; @@ -84725,7 +81056,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *array; uint32_t size; @@ -84740,14 +81071,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_VA if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init_mixed(Z_ARRVAL_P(array)); } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { ZVAL_ARR(array, zend_new_array(0)); ZEND_VM_NEXT_OPCODE(); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -84757,7 +81088,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_VAR SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); do { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -84769,7 +81100,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_VAR offset_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { key = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { if (ZEND_HANDLE_NUMERIC(key, hval)) { goto num_index_dim; } @@ -84781,7 +81112,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_VAR hval = Z_LVAL_P(offset); num_index_dim: zend_hash_index_del(ht, hval); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { offset = Z_REFVAL_P(offset); goto offset_again; } else if (Z_TYPE_P(offset) == IS_DOUBLE) { @@ -84810,7 +81141,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_VAR zend_use_resource_as_offset(offset); hval = Z_RES_HANDLE_P(offset); goto num_index_dim; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + } else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); key = ZSTR_EMPTY_ALLOC(); goto str_index_dim; @@ -84827,11 +81158,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_VAR if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { container = ZVAL_UNDEFINED_OP1(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { offset = ZVAL_UNDEFINED_OP2(); } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { offset++; } Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset); @@ -84849,7 +81180,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_VAR ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -84858,7 +81189,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_VAR SAVE_OPLINE(); container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { @@ -84875,7 +81206,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_VAR break; } } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(offset); } else { name = zval_try_get_tmp_string(offset, &tmp_name); @@ -84883,8 +81214,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_VAR break; } } - Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } } while (0); @@ -84894,7 +81225,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_VAR ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_VAR_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -84980,9 +81311,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_VAR_TMP } /* Set the new yielded key */ - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *key = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + if (IS_TMP_VAR != IS_UNUSED) { + zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { key = Z_REFVAL_P(key); } ZVAL_COPY(&generator->key, key); @@ -85015,210 +81346,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_VAR_TMP ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_STRICT_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (0 || UNEXPECTED(0)) { - zend_refcounted *garbage = NULL; - - value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(0)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES()); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (0 || UNEXPECTED(1)) { - zend_refcounted *garbage = NULL; - - value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(1)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES()); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_VAR_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_STRICT_SPEC_VAR_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (0 || UNEXPECTED(0)) { - zend_refcounted *garbage = NULL; - - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(0)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES()); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (0 || UNEXPECTED(1)) { - zend_refcounted *garbage = NULL; - - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(1)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES()); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_REF_SPEC_VAR_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -85406,6 +81533,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_UNUSED == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + if (IS_VAR & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -85722,160 +81861,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_UNUSED == IS_UNUSED) { - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = NULL; - if (IS_UNUSED == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = NULL; - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_UNUSED == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = NULL; - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = NULL; - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = NULL; -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_UNUSED != IS_UNUSED) { - - - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -87037,22 +83022,25 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MAKE_REF_SPEC_VAR_ ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_GET_TYPE_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DEREF_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *op1; - zend_string *type; - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - type = zend_zval_get_legacy_type(op1); - if (EXPECTED(type)) { - ZVAL_INTERNED_STR(EX_VAR(opline->result.var), type); + zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + + if (Z_TYPE_P(value) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(value); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(EX_VAR(opline->result.var)); + } } else { - ZVAL_STRING(EX_VAR(opline->result.var), "unknown type"); + ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); + + ZEND_VM_NEXT_OPCODE(); } static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -87077,21 +83065,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_V ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CASE_STRICT_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_var_deref(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - - - ZEND_VM_SMART_BRANCH(result, 1); -} - static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -87185,7 +83158,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -87493,6 +83466,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_CV == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + if (IS_VAR & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -87566,6 +83551,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { + if (IS_VAR == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -87767,7 +83764,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -87922,162 +83919,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - - - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_obj has two opcodes! */ - 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -88234,7 +84076,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_VA 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -88547,160 +84389,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VA ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_CV == IS_UNUSED) { - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CV == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = EX_VAR(opline->op2.var); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_CV != IS_UNUSED) { - - - } - zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -88993,7 +84681,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -89032,7 +84720,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -89934,7 +85622,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -90073,11 +85761,15 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND SAVE_OPLINE(); container = &EX(This); + if (IS_UNUSED & (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 (IS_UNUSED == IS_CONST || (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { do { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + if ((IS_UNUSED & IS_CV) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; @@ -90290,6 +85982,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ SAVE_OPLINE(); container = &EX(This); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ if (IS_UNUSED == IS_CONST || (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -90418,6 +86112,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { + if (IS_UNUSED == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -90597,7 +86303,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -90753,163 +86459,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = &EX(This); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - - - - - /* assign_obj has two opcodes! */ - 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -91067,7 +86617,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -91105,7 +86655,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -91144,7 +86694,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_INIT_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -92091,7 +87641,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_CONSTA ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object; @@ -92106,7 +87656,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC SAVE_OPLINE(); object = &EX(This); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); do { value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); @@ -92127,7 +87677,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC assign_op_object: /* here we are sure we are dealing with an object */ zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(property); } else { name = zval_try_get_tmp_string(property, &tmp_name); @@ -92136,7 +87686,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -92171,7 +87721,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC } else { zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } } while (0); @@ -92184,8 +87734,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object; @@ -92199,7 +87749,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_U SAVE_OPLINE(); object = &EX(This); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -92218,7 +87768,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_U pre_incdec_object: /* here we are sure we are dealing with an object */ zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(property); } else { name = zval_try_get_tmp_string(property, &tmp_name); @@ -92227,7 +87777,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_U break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -92240,7 +87790,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_U } else { zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } } while (0); @@ -92251,7 +87801,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_U ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object; @@ -92265,7 +87815,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_ SAVE_OPLINE(); object = &EX(This); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -92284,7 +87834,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_ post_incdec_object: /* here we are sure we are dealing with an object */ zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(property); } else { name = zval_try_get_tmp_string(property, &tmp_name); @@ -92293,7 +87843,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_ break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -92304,7 +87854,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_ } else { zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } } while (0); @@ -92315,7 +87865,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -92323,11 +87873,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_U SAVE_OPLINE(); container = &EX(This); + if (IS_UNUSED & (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 (IS_UNUSED == IS_CONST || (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { do { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + if ((IS_UNUSED & IS_CV) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; @@ -92336,7 +87890,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_U if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - zend_wrong_property_read(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + zend_wrong_property_read(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); ZVAL_NULL(EX_VAR(opline->result.var)); goto fetch_obj_r_finish; } while (0); @@ -92348,7 +87902,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_U zend_string *name, *tmp_name; zval *retval; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { @@ -92408,7 +87962,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_U /* Fall through to read_property for hooks. */ } else if (EXPECTED(zobj->properties != NULL)) { ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); @@ -92441,9 +87995,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_U } } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); break; @@ -92467,7 +88021,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_U } #endif - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -92486,7 +88040,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_U ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *property, *container, *result; @@ -92494,11 +88048,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_U SAVE_OPLINE(); container = &EX(This); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); zend_fetch_property_address( - result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), - (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), + result, container, IS_UNUSED, property, IS_TMP_VAR, + ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_UNUSED == IS_VAR) { @@ -92507,16 +88061,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_U ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *property, *container, *result; SAVE_OPLINE(); container = &EX(This); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -92524,7 +88078,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -92532,6 +88086,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ SAVE_OPLINE(); container = &EX(This); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ if (IS_UNUSED == IS_CONST || (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -92542,7 +88098,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ break; } } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { + if (IS_TMP_VAR == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); } ZVAL_NULL(EX_VAR(opline->result.var)); @@ -92556,7 +88112,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ zend_string *name, *tmp_name; zval *retval; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { @@ -92583,7 +88139,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ /* Fall through to read_property for hooks. */ } else if (EXPECTED(zobj->properties != NULL)) { ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); @@ -92616,9 +88172,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ } } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); break; @@ -92627,7 +88183,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -92646,7 +88202,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 USE_OPLINE @@ -92657,22 +88213,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG if ((IS_UNUSED & (IS_CONST|IS_TMP_VAR))) { ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_UNUSED == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container, *property, *result; SAVE_OPLINE(); container = &EX(This); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -92680,7 +88248,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SP ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object, *value, tmp; @@ -92697,14 +88265,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN object = Z_REFVAL_P(object); goto assign_object; } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); value = &EG(uninitialized_zval); goto free_and_exit_assign_obj; } assign_object: zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -92730,7 +88298,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN } } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { zobj = zend_lazy_object_init(zobj); if (!zobj) { @@ -92798,9 +88366,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN /* Fall through to write_property for hooks. */ } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { @@ -92813,9 +88381,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -92836,8 +88404,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object, *value, tmp; @@ -92854,14 +88422,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN object = Z_REFVAL_P(object); goto assign_object; } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); value = &EG(uninitialized_zval); goto free_and_exit_assign_obj; } assign_object: zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -92887,7 +88455,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN } } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { zobj = zend_lazy_object_init(zobj); if (!zobj) { @@ -92955,9 +88523,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN /* Fall through to write_property for hooks. */ } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); @@ -92969,9 +88537,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -92991,163 +88559,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = &EX(This); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object, *value, tmp; @@ -93164,14 +88577,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN object = Z_REFVAL_P(object); goto assign_object; } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); value = &EG(uninitialized_zval); goto free_and_exit_assign_obj; } assign_object: zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -93197,7 +88610,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN } } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { zobj = zend_lazy_object_init(zobj); if (!zobj) { @@ -93265,9 +88678,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN /* Fall through to write_property for hooks. */ } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { @@ -93280,9 +88693,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -93303,8 +88716,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *property, *container, *value_ptr; @@ -93312,26 +88725,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE SAVE_OPLINE(); container = &EX(This); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); if (1) { if (IS_UNUSED == IS_UNUSED) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } } else { - zend_assign_to_property_reference(container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_property_reference(container, IS_UNUSED, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); } @@ -93340,8 +88753,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *property, *container, *value_ptr; @@ -93349,26 +88762,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE SAVE_OPLINE(); container = &EX(This); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); if (1) { if (IS_UNUSED == IS_UNUSED) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } } else { - zend_assign_to_property_reference(container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_property_reference(container, IS_UNUSED, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); } @@ -93378,8 +88791,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_INIT_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_string **rope; @@ -93387,23 +88800,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_INIT_SPEC_UNU /* Compiler allocates the necessary number of zval slots to keep the rope */ rope = (zend_string**)EX_VAR(opline->result.var); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); rope[0] = Z_STR_P(var); if (UNEXPECTED(Z_REFCOUNTED_P(var))) { Z_ADDREF_P(var); } } else { - var = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + var = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(var) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { + if (IS_TMP_VAR == IS_CV) { rope[0] = zend_string_copy(Z_STR_P(var)); } else { rope[0] = Z_STR_P(var); } } else { SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); } rope[0] = zval_get_string_func(var); @@ -93414,36 +88827,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_INIT_SPEC_UNU ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *class_name; USE_OPLINE SAVE_OPLINE(); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_TMP_VAR == IS_UNUSED) { Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(NULL, opline->op1.num); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + } else if (IS_TMP_VAR == IS_CONST) { zend_class_entry *ce = CACHED_PTR(opline->extended_value); if (UNEXPECTED(ce == NULL)) { - class_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + class_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); ce = zend_fetch_class_by_name(Z_STR_P(class_name), Z_STR_P(class_name + 1), opline->op1.num); CACHE_PTR(opline->extended_value, ce); } Z_CE_P(EX_VAR(opline->result.var)) = ce; } else { - class_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + class_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); try_class_name: if (Z_TYPE_P(class_name) == IS_OBJECT) { Z_CE_P(EX_VAR(opline->result.var)) = Z_OBJCE_P(class_name); } else if (Z_TYPE_P(class_name) == IS_STRING) { Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class(Z_STR_P(class_name), opline->op1.num); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) { + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_TYPE_P(class_name) == IS_REFERENCE) { class_name = Z_REFVAL_P(class_name); goto try_class_name; } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(class_name) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -93457,7 +88870,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_CLASS_SPEC_U ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; @@ -93472,19 +88885,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S object = &EX(This); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR != IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && + if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); if (UNEXPECTED(EG(exception) != NULL)) { @@ -93526,14 +88939,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S if (IS_UNUSED == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { object = ZVAL_UNDEFINED_OP1(); if (UNEXPECTED(EG(exception) != NULL)) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } HANDLE_EXCEPTION(); } } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); } zend_invalid_method_call(object, function_name); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -93546,18 +88959,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S called_scope = obj->ce; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_TMP_VAR == IS_CONST && EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); } /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); @@ -93568,7 +88981,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S } HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_TMP_VAR == IS_CONST && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); @@ -93584,7 +88997,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S } } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } @@ -93615,7 +89028,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; @@ -93635,7 +89048,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { CACHE_PTR(opline->result.num, ce); } } @@ -93650,24 +89063,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD } if (IS_UNUSED == IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && + IS_TMP_VAR == IS_CONST && EXPECTED((fbc = CACHED_PTR(opline->result.num + sizeof(void*))) != NULL)) { /* nothing to do */ } else if (IS_UNUSED != IS_CONST && - (IS_TMP_VAR|IS_VAR) == IS_CONST && + IS_TMP_VAR == IS_CONST && EXPECTED(CACHED_PTR(opline->result.num) == ce)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); - } else if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + } else if (IS_TMP_VAR != IS_UNUSED) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR != IS_CONST) { if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { + if (IS_TMP_VAR & (IS_VAR|IS_CV) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -93683,7 +89096,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD if (ce->get_static_method) { fbc = ce->get_static_method(ce, Z_STR_P(function_name)); } else { - fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); } if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { @@ -93692,7 +89105,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_TMP_VAR == IS_CONST && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(!(fbc->common.scope->ce_flags & ZEND_ACC_TRAIT))) { CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc); @@ -93700,7 +89113,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } } else { @@ -93748,7 +89161,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_STATIC_METHOD ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *array; uint32_t size; @@ -93770,7 +89183,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_UN } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -93779,7 +89192,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_UNU SAVE_OPLINE(); container = &EX(This); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { @@ -93796,7 +89209,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_UNU break; } } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(offset); } else { name = zval_try_get_tmp_string(offset, &tmp_name); @@ -93804,8 +89217,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_UNU break; } } - Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } } while (0); @@ -93816,7 +89229,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_UNU ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -93826,7 +89239,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP SAVE_OPLINE(); container = &EX(This); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if (IS_UNUSED == IS_CONST || (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -93842,7 +89255,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP } } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(offset); } else { name = zval_try_get_tmp_string(offset, &tmp_name); @@ -93854,9 +89267,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP result = (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -93867,7 +89280,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -93954,9 +89367,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_UNUSED_ } /* Set the new yielded key */ - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *key = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + if (IS_TMP_VAR != IS_UNUSED) { + zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { key = Z_REFVAL_P(key); } ZVAL_COPY(&generator->key, key); @@ -94889,7 +90302,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -95028,11 +90441,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_U SAVE_OPLINE(); container = &EX(This); + if (IS_UNUSED & (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 (IS_UNUSED == IS_CONST || (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { do { - if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + if ((IS_UNUSED & IS_CV) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; @@ -95240,6 +90657,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ SAVE_OPLINE(); container = &EX(This); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ if (IS_UNUSED == IS_CONST || (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -95368,6 +90787,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { + if (IS_UNUSED == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -95547,7 +90978,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -95703,163 +91134,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = &EX(This); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - - - - - /* assign_obj has two opcodes! */ - 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -96017,7 +91292,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_UN 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -96055,7 +91330,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -96094,7 +91369,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ROPE_INIT_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -97298,6 +92573,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_BY_REF_SPEC + // FIXME: Don't create the ref in the first place? + zend_return_unwrap_ref(execute_data, return_value); + ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); } @@ -99130,7 +94408,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -99402,13 +94680,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_C SAVE_OPLINE(); container = EX_VAR(opline->op1.var); + if (IS_CV & (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 = RT_CONSTANT(opline, opline->op2); if (IS_CV != IS_CONST) { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_array: value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CONST, 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 (IS_CV == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { goto fetch_dim_r_array; @@ -99471,6 +94753,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_ SAVE_OPLINE(); container = EX_VAR(opline->op1.var); + /* 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, RT_CONSTANT(opline, opline->op2), IS_CONST OPLINE_CC EXECUTE_DATA_CC); @@ -99494,6 +94778,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_CONST == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + if (IS_CV & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -99522,11 +94818,15 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND SAVE_OPLINE(); container = EX_VAR(opline->op1.var); + if (IS_CV & (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 (IS_CV == IS_CONST || (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { do { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + if ((IS_CV & IS_CV) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; @@ -99739,6 +95039,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ if (IS_CV == IS_CONST || (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -99867,6 +95169,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { + if (IS_CV == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -100046,7 +95360,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -100202,163 +95516,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, RT_CONSTANT(opline, opline->op2) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CONST == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); - } else { - name = zval_try_get_tmp_string(RT_CONSTANT(opline, opline->op2), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if (IS_CONST != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - - - - - /* assign_obj has two opcodes! */ - 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -100516,7 +95674,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -100831,161 +95989,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_CONST == IS_UNUSED) { - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = RT_CONSTANT(opline, opline->op2); - if (IS_CONST == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CONST == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CONST == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = RT_CONSTANT(opline, opline->op2); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = RT_CONSTANT(opline, opline->op2); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = RT_CONSTANT(opline, opline->op2); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_CONST != IS_UNUSED) { - - - } - - - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -101242,7 +96245,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -101281,7 +96284,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -102642,14 +97645,14 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); div_function(EX_VAR(opline->result.var), op1, op2); @@ -102657,14 +97660,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DIV_SPEC_CV_TMPVAR ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); pow_function(EX_VAR(opline->result.var), op1, op2); @@ -102672,23 +97675,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POW_SPEC_CV_TMPVAR ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; op1 = EX_VAR(opline->op1.var); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { zend_string *op1_str = Z_STR_P(op1); zend_string *op2_str = Z_STR_P(op2); zend_string *str; uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); } else { ZVAL_STR(EX_VAR(opline->result.var), op2_str); @@ -102696,13 +97699,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CV_TMP if (IS_CV & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op1_str, 0); } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + } else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { if (IS_CV == IS_CONST || IS_CV == IS_CV) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } else if (IS_CV != IS_CONST && IS_CV != IS_CV && @@ -102716,7 +97719,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CV_TMP memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); GC_ADD_FLAGS(str, flags); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } else { @@ -102728,7 +97731,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CV_TMP if (IS_CV & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op1_str, 0); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } @@ -102739,7 +97742,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CV_TMP if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) { op1 = ZVAL_UNDEFINED_OP1(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { op2 = ZVAL_UNDEFINED_OP2(); } concat_function(EX_VAR(opline->result.var), op1, op2); @@ -102750,15 +97753,47 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_CONCAT_SPEC_CV_TMP } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + result = fast_is_identical_function(op1, op2); + + + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *op1, *op2; + bool result; + + SAVE_OPLINE(); + op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + result = fast_is_not_identical_function(op1, op2); + + + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + ZEND_VM_SMART_BRANCH(result, 1); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; double d1, d2; op1 = EX_VAR(opline->op1.var); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) { /* pass */ } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { @@ -102795,7 +97830,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_T if (IS_CV & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_str(op1); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_str(op2); } if (result) { @@ -102808,15 +97843,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_T ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; double d1, d2; op1 = EX_VAR(opline->op1.var); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) { /* pass */ } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { @@ -102853,7 +97888,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_T if (IS_CV & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_str(op1); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_str(op2); } if (result) { @@ -102866,15 +97901,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_T ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; double d1, d2; op1 = EX_VAR(opline->op1.var); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) { /* pass */ } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { @@ -102911,7 +97946,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_T if (IS_CV & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_str(op1); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_str(op2); } if (result) { @@ -102924,15 +97959,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_EQUAL_SPEC_CV_T ZEND_VM_DISPATCH_TO_HELPER(zend_is_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; double d1, d2; op1 = EX_VAR(opline->op1.var); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) { /* pass */ } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { @@ -102969,7 +98004,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_ if (IS_CV & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_str(op1); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_str(op2); } if (!result) { @@ -102982,15 +98017,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_ ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; double d1, d2; op1 = EX_VAR(opline->op1.var); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) { /* pass */ } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { @@ -103027,7 +98062,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_ if (IS_CV & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_str(op1); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_str(op2); } if (!result) { @@ -103040,15 +98075,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_ ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; double d1, d2; op1 = EX_VAR(opline->op1.var); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (1 && IS_CV == IS_CONST && (IS_TMP_VAR|IS_VAR) == IS_CONST) { + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (1 && IS_CV == IS_CONST && IS_TMP_VAR == IS_CONST) { /* pass */ } else if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) { if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) { @@ -103085,7 +98120,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_ if (IS_CV & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_str(op1); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zval_ptr_dtor_str(op2); } if (!result) { @@ -103098,14 +98133,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_EQUAL_SPEC_ ZEND_VM_DISPATCH_TO_HELPER(zend_is_not_equal_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX op1, op2)); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); compare_function(EX_VAR(opline->result.var), op1, op2); @@ -103113,14 +98148,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SPACESHIP_SPEC_CV_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_XOR_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_XOR_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; SAVE_OPLINE(); op1 = _get_zval_ptr_cv_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); boolean_xor_function(EX_VAR(opline->result.var), op1, op2); @@ -103128,7 +98163,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_BOOL_XOR_SPEC_CV_T ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object; @@ -103143,7 +98178,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC SAVE_OPLINE(); object = EX_VAR(opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); do { value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); @@ -103164,7 +98199,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC assign_op_object: /* here we are sure we are dealing with an object */ zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(property); } else { name = zval_try_get_tmp_string(property, &tmp_name); @@ -103173,7 +98208,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -103208,7 +98243,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC } else { zend_assign_op_overloaded_property(zobj, name, cache_slot, value OPLINE_CC EXECUTE_DATA_CC); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } } while (0); @@ -103221,8 +98256,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *var_ptr; @@ -103237,15 +98272,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC SEPARATE_ARRAY(container); ht = Z_ARRVAL_P(container); assign_dim_op_new_array: - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_UNUSED) { var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval)); if (UNEXPECTED(!var_ptr)) { zend_cannot_add_element(); goto assign_dim_op_ret_null; } } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { var_ptr = zend_fetch_dimension_address_inner_RW_CONST(ht, dim EXECUTE_DATA_CC); } else { var_ptr = zend_fetch_dimension_address_inner_RW(ht, dim EXECUTE_DATA_CC); @@ -103258,7 +98293,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC value = get_op_data_zval_ptr_r((opline+1)->op1_type, (opline+1)->op1); do { - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { + if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_ISREF_P(var_ptr))) { zend_reference *ref = Z_REF_P(var_ptr); var_ptr = Z_REFVAL_P(var_ptr); if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(ref))) { @@ -103284,8 +98319,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_object *obj = Z_OBJ_P(container); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_binary_assign_op_obj_dim(obj, dim OPLINE_CC EXECUTE_DATA_CC); @@ -103308,7 +98343,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC } goto assign_dim_op_new_array; } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); assign_dim_op_ret_null: FREE_OP((opline+1)->op1_type, (opline+1)->op1.var); @@ -103324,14 +98359,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OP_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OP_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *var_ptr; zval *value; SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); var_ptr = _get_zval_ptr_cv_BP_VAR_RW(opline->op1.var EXECUTE_DATA_CC); do { @@ -103356,7 +98391,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OP_SPEC_CV_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object; @@ -103370,7 +98405,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_C SAVE_OPLINE(); object = EX_VAR(opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -103389,7 +98424,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_C pre_incdec_object: /* here we are sure we are dealing with an object */ zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(property); } else { name = zval_try_get_tmp_string(property, &tmp_name); @@ -103398,7 +98433,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_C break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -103411,7 +98446,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_C } else { zend_pre_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } } while (0); @@ -103422,7 +98457,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_PRE_INC_OBJ_SPEC_C ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object; @@ -103436,7 +98471,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_ SAVE_OPLINE(); object = EX_VAR(opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { @@ -103455,7 +98490,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_ post_incdec_object: /* here we are sure we are dealing with an object */ zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(property); } else { name = zval_try_get_tmp_string(property, &tmp_name); @@ -103464,7 +98499,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_ break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; + cache_slot = (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -103475,7 +98510,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_ } else { zend_post_incdec_overloaded_property(zobj, name, cache_slot OPLINE_CC EXECUTE_DATA_CC); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } } while (0); @@ -103486,20 +98521,24 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_POST_INC_OBJ_SPEC_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container, *dim, *value; SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_CV & (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_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if (IS_CV != IS_CONST) { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_array: - value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_R EXECUTE_DATA_CC); + value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_TMP_VAR, 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 (IS_CV == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { goto fetch_dim_r_array; @@ -103508,13 +98547,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_C } } else { fetch_dim_r_slow: - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } zend_fetch_dimension_address_read_R_slow(container, dim OPLINE_CC EXECUTE_DATA_CC); } } else { - zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_dimension_address_read_R(container, dim, IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); } zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -103522,14 +98561,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_C ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_W_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_W(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_dimension_address_W(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -103537,14 +98576,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_W_SPEC_C ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_RW_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_RW(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_dimension_address_RW(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -103552,21 +98591,23 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_RW_SPEC_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_read_IS(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); + /* 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_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 USE_OPLINE @@ -103576,23 +98617,35 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_W_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_TMP_VAR == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_CV & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - zend_fetch_dimension_address_UNSET(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), (IS_TMP_VAR|IS_VAR) OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_dimension_address_UNSET(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), IS_TMP_VAR OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -103600,7 +98653,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_UNSET_SP ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -103608,11 +98661,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_C SAVE_OPLINE(); container = EX_VAR(opline->op1.var); + if (IS_CV & (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 (IS_CV == IS_CONST || (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { do { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + if ((IS_CV & IS_CV) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; @@ -103621,7 +98678,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_C if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } - zend_wrong_property_read(container, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + zend_wrong_property_read(container, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); ZVAL_NULL(EX_VAR(opline->result.var)); goto fetch_obj_r_finish; } while (0); @@ -103633,7 +98690,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_C zend_string *name, *tmp_name; zval *retval; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_REF /* FUNC_ARG fetch may contain it */); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { @@ -103693,7 +98750,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_C /* Fall through to read_property for hooks. */ } else if (EXPECTED(zobj->properties != NULL)) { ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); @@ -103726,9 +98783,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_C } } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); break; @@ -103752,7 +98809,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_C } #endif - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -103771,7 +98828,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_C ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *property, *container, *result; @@ -103779,11 +98836,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_C SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); zend_fetch_property_address( - result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), - (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), + result, container, IS_CV, property, IS_TMP_VAR, + ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_CV == IS_VAR) { @@ -103792,16 +98849,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_W_SPEC_C ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *property, *container, *result; SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_CV, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -103809,7 +98866,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_RW_SPEC_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -103817,6 +98874,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ if (IS_CV == IS_CONST || (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -103827,7 +98886,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ break; } } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { + if (IS_TMP_VAR == IS_CV && Z_TYPE_P(EX_VAR(opline->op2.var)) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); } ZVAL_NULL(EX_VAR(opline->result.var)); @@ -103841,7 +98900,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ zend_string *name, *tmp_name; zval *retval; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { cache_slot = CACHE_ADDR(opline->extended_value); if (EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { @@ -103868,7 +98927,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ /* Fall through to read_property for hooks. */ } else if (EXPECTED(zobj->properties != NULL)) { ZEND_ASSERT(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset)); - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (!IS_UNKNOWN_DYNAMIC_PROPERTY_OFFSET(prop_offset)) { uintptr_t idx = ZEND_DECODE_DYN_PROP_OFFSET(prop_offset); @@ -103901,9 +98960,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ } } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { ZVAL_UNDEF(EX_VAR(opline->result.var)); break; @@ -103912,7 +98971,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ retval = zobj->handlers->read_property(zobj, name, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -103931,7 +98990,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { #if 0 USE_OPLINE @@ -103942,22 +99001,34 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG if ((IS_CV & (IS_CONST|IS_TMP_VAR))) { ZEND_VM_TAIL_CALL(zend_use_tmp_in_write_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { - ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + if (IS_CV == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } + ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container, *property, *result; SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_CV, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -103965,7 +99036,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_UNSET_SP ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object, *value, tmp; @@ -103982,14 +99053,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV object = Z_REFVAL_P(object); goto assign_object; } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); value = &EG(uninitialized_zval); goto free_and_exit_assign_obj; } assign_object: zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -104015,7 +99086,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV } } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { zobj = zend_lazy_object_init(zobj); if (!zobj) { @@ -104083,9 +99154,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV /* Fall through to write_property for hooks. */ } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { @@ -104098,9 +99169,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -104121,8 +99192,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object, *value, tmp; @@ -104139,14 +99210,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV object = Z_REFVAL_P(object); goto assign_object; } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); value = &EG(uninitialized_zval); goto free_and_exit_assign_obj; } assign_object: zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -104172,7 +99243,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV } } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { zobj = zend_lazy_object_init(zobj); if (!zobj) { @@ -104240,9 +99311,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV /* Fall through to write_property for hooks. */ } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); UNDEF_RESULT(); @@ -104254,164 +99325,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - - - /* assign_obj has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -104431,8 +99347,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object, *value, tmp; @@ -104449,14 +99365,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV object = Z_REFVAL_P(object); goto assign_object; } - zend_throw_non_object_error(object, _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); + zend_throw_non_object_error(object, _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); value = &EG(uninitialized_zval); goto free_and_exit_assign_obj; } assign_object: zobj = Z_OBJ_P(object); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { void **cache_slot = CACHE_ADDR(opline->extended_value); uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); @@ -104482,7 +99398,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV } } } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { zobj = zend_lazy_object_init(zobj); if (!zobj) { @@ -104550,9 +99466,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV /* Fall through to write_property for hooks. */ } } - name = Z_STR_P(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC)); + name = Z_STR_P(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC)); } else { - name = zval_try_get_tmp_string(_get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC), &tmp_name); + name = zval_try_get_tmp_string(_get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC), &tmp_name); if (UNEXPECTED(!name)) { @@ -104565,9 +99481,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV ZVAL_DEREF(value); } - value = zobj->handlers->write_property(zobj, name, value, ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); + value = zobj->handlers->write_property(zobj, name, value, (IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -104588,8 +99504,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object_ptr, *orig_object_ptr; @@ -104604,7 +99520,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_TMP_VAR == IS_UNUSED) { value = RT_CONSTANT((opline+1), (opline+1)->op1); if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { HashTable *ht = Z_ARRVAL_P(object_ptr); @@ -104642,8 +99558,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV } } } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); @@ -104671,10 +99587,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_object *obj = Z_OBJ_P(object_ptr); GC_ADDREF(obj); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + } else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } @@ -104692,13 +99608,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_TMP_VAR == IS_UNUSED) { zend_use_new_element_for_string(); UNDEF_RESULT(); } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); value = RT_CONSTANT((opline+1), (opline+1)->op1); zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); @@ -104708,7 +99624,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); UNDEF_RESULT(); @@ -104729,7 +99645,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV } } else { zend_use_scalar_as_array(); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); assign_dim_error: @@ -104738,7 +99654,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV } } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + if (IS_TMP_VAR != IS_UNUSED) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } @@ -104747,7 +99663,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *object_ptr, *orig_object_ptr; @@ -104762,7 +99678,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_TMP_VAR == IS_UNUSED) { value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { HashTable *ht = Z_ARRVAL_P(object_ptr); @@ -104800,8 +99716,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV } } } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); } else { variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); @@ -104829,43 +99745,200 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV zend_object *obj = Z_OBJ_P(object_ptr); GC_ADDREF(obj); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { + dim = ZVAL_UNDEFINED_OP2(); + } else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { + ZVAL_DEREF(value); + } + + zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); + + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { + zend_objects_store_del(obj); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (IS_TMP_VAR == IS_UNUSED) { + zend_use_new_element_for_string(); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + } else { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + } + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (Z_ISREF_P(orig_object_ptr) + && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) + && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + UNDEF_RESULT(); + } else { + HashTable *ht = zend_new_array(8); + uint8_t old_type = Z_TYPE_P(object_ptr); + + ZVAL_ARR(object_ptr, ht); + if (UNEXPECTED(old_type == IS_FALSE)) { + GC_ADDREF(ht); + zend_false_to_array_deprecated(); + if (UNEXPECTED(GC_DELREF(ht) == 0)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + goto try_assign_dim_array; + } + } else { + zend_use_scalar_as_array(); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); +assign_dim_error: + zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } + } + } + if (IS_TMP_VAR != IS_UNUSED) { + zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + } + + + /* assign_dim has two opcodes! */ + ZEND_VM_NEXT_OPCODE_EX(1, 2); +} + +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zval *object_ptr, *orig_object_ptr; + zval *value; + zval *variable_ptr; + zval *dim; + zend_refcounted *garbage = NULL; + + SAVE_OPLINE(); + orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); + + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { +try_assign_dim_array: + SEPARATE_ARRAY(object_ptr); + if (IS_TMP_VAR == IS_UNUSED) { + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { + HashTable *ht = Z_ARRVAL_P(object_ptr); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_ADDREF(ht); + } + value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { + zend_array_destroy(ht); + goto assign_dim_error; + } + } + if (IS_CV == IS_CV || IS_CV == IS_VAR) { + ZVAL_DEREF(value); + } + value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); + if (UNEXPECTED(value == NULL)) { + zend_cannot_add_element(); + goto assign_dim_error; + } else if (IS_CV == IS_CV) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + } else if (IS_CV == IS_VAR) { + zval *free_op_data = EX_VAR((opline+1)->op1.var); + if (Z_ISREF_P(free_op_data)) { + if (Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zval_ptr_dtor_nogc(free_op_data); + } + } else if (IS_CV == IS_CONST) { + if (UNEXPECTED(Z_REFCOUNTED_P(value))) { + Z_ADDREF_P(value); + } + } + } else { + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } else { + variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); + } + if (UNEXPECTED(variable_ptr == NULL)) { + goto assign_dim_error; + } + value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); + value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); + } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), value); + } + if (garbage) { + GC_DTOR_NO_REF(garbage); + } + } else { + if (EXPECTED(Z_ISREF_P(object_ptr))) { + object_ptr = Z_REFVAL_P(object_ptr); + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { + goto try_assign_dim_array; + } + } + if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { + zend_object *obj = Z_OBJ_P(object_ptr); + + GC_ADDREF(obj); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + } else if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { dim++; } - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { + value = EX_VAR((opline+1)->op1.var); + if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_TMP_VAR & (IS_CV|IS_VAR)) { + } else if (IS_CV & (IS_CV|IS_VAR)) { ZVAL_DEREF(value); } zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + if (UNEXPECTED(GC_DELREF(obj) == 0)) { zend_objects_store_del(obj); } } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + if (IS_TMP_VAR == IS_UNUSED) { zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + + UNDEF_RESULT(); } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_tmp((opline+1)->op1.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + value = EX_VAR((opline+1)->op1.var); zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + + } } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { if (Z_ISREF_P(orig_object_ptr) && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + + UNDEF_RESULT(); } else { HashTable *ht = zend_new_array(8); @@ -104884,15 +99957,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV } } else { zend_use_scalar_as_array(); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + dim = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); + + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { + if (IS_TMP_VAR != IS_UNUSED) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } @@ -104901,319 +99975,67 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; zval *value; zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); + value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = EX_VAR(opline->op1.var); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (0 || UNEXPECTED(0)) { + zend_refcounted *garbage = NULL; + + value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(0)) { ZVAL_COPY(EX_VAR(opline->result.var), value); } if (garbage) { GC_DTOR_NO_REF(garbage); } } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES()); } - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + /* zend_assign_to_variable() always takes care of op2, never free it! */ + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE - zval *object_ptr, *orig_object_ptr; zval *value; zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); + value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + variable_ptr = EX_VAR(opline->op1.var); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - value = EX_VAR((opline+1)->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_CV == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_CV == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_CV == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_cv_BP_VAR_R((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + if (0 || UNEXPECTED(1)) { + zend_refcounted *garbage = NULL; + + value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); + if (UNEXPECTED(1)) { ZVAL_COPY(EX_VAR(opline->result.var), value); } if (garbage) { GC_DTOR_NO_REF(garbage); } } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = EX_VAR((opline+1)->op1.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_CV & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { - zend_use_new_element_for_string(); - - - UNDEF_RESULT(); - } else { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - value = EX_VAR((opline+1)->op1.var); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - - - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - - - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); -assign_dim_error: - - - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); + value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES()); } - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); + /* zend_assign_to_variable() always takes care of op2, never free it! */ + + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *property, *container, *value_ptr; @@ -105221,26 +100043,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); value_ptr = _get_zval_ptr_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); if (1) { if (IS_CV == IS_UNUSED) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } } else { - zend_assign_to_property_reference(container, IS_CV, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_property_reference(container, IS_CV, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); } @@ -105249,8 +100071,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *property, *container, *value_ptr; @@ -105258,26 +100080,26 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + property = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); value_ptr = _get_zval_ptr_cv_BP_VAR_W((opline+1)->op1.var EXECUTE_DATA_CC); if (1) { if (IS_CV == IS_UNUSED) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { zend_assign_to_property_reference_this_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { zend_assign_to_property_reference_this_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { zend_assign_to_property_reference_var_const(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } else { zend_assign_to_property_reference_var_var(container, property, value_ptr OPLINE_CC EXECUTE_DATA_CC); } } } else { - zend_assign_to_property_reference(container, IS_CV, property, (IS_TMP_VAR|IS_VAR), value_ptr OPLINE_CC EXECUTE_DATA_CC); + zend_assign_to_property_reference(container, IS_CV, property, IS_TMP_VAR, value_ptr OPLINE_CC EXECUTE_DATA_CC); } @@ -105287,8 +100109,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */ +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *op1, *op2; @@ -105296,16 +100118,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_C op1 = EX_VAR(opline->op1.var); - op2 = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if ((IS_CV == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && - ((IS_TMP_VAR|IS_VAR) == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { + (IS_TMP_VAR == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { zend_string *op1_str = Z_STR_P(op1); zend_string *op2_str = Z_STR_P(op2); zend_string *str; uint32_t flags = ZSTR_GET_COPYABLE_CONCAT_PROPERTIES_BOTH(op1_str, op2_str); if (IS_CV != IS_CONST && UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST || (IS_TMP_VAR|IS_VAR) == IS_CV) { + if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_CV) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op2_str); } else { ZVAL_STR(EX_VAR(opline->result.var), op2_str); @@ -105313,13 +100135,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_C if (IS_CV & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op1_str, 0); } - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { + } else if (IS_TMP_VAR != IS_CONST && UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { if (IS_CV == IS_CONST || IS_CV == IS_CV) { ZVAL_STR_COPY(EX_VAR(opline->result.var), op1_str); } else { ZVAL_STR(EX_VAR(opline->result.var), op1_str); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } else if (IS_CV != IS_CONST && IS_CV != IS_CV && @@ -105330,7 +100152,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_C memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); GC_ADD_FLAGS(str, flags); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } else { @@ -105342,7 +100164,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_C if (IS_CV & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op1_str, 0); } - if ((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) { + if (IS_TMP_VAR & (IS_TMP_VAR|IS_VAR)) { zend_string_release_ex(op2_str, 0); } } @@ -105360,12 +100182,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_C } op1_str = zval_get_string_func(op1); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { op2_str = Z_STR_P(op2); } else if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) { op2_str = zend_string_copy(Z_STR_P(op2)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); } op2_str = zval_get_string_func(op2); @@ -105373,7 +100195,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_C do { if (IS_CV != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op1_str) == 0)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { if (UNEXPECTED(Z_REFCOUNTED_P(op2))) { GC_ADDREF(op2_str); } @@ -105383,7 +100205,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_C break; } } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { if (UNEXPECTED(ZSTR_LEN(op2_str) == 0)) { if (IS_CV == IS_CONST) { if (UNEXPECTED(Z_REFCOUNTED_P(op1))) { @@ -105404,7 +100226,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_C if (IS_CV != IS_CONST) { zend_string_release_ex(op1_str, 0); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_string_release_ex(op2_str, 0); } } while (0); @@ -105414,7 +100236,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_C ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *function_name; @@ -105429,19 +100251,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S object = EX_VAR(opline->op1.var); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR != IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && + if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { do { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && Z_ISREF_P(function_name)) { function_name = Z_REFVAL_P(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { break; } - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { + } else if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(function_name) == IS_UNDEF)) { ZVAL_UNDEFINED_OP2(); if (UNEXPECTED(EG(exception) != NULL)) { @@ -105483,14 +100305,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(object) == IS_UNDEF)) { object = ZVAL_UNDEFINED_OP1(); if (UNEXPECTED(EG(exception) != NULL)) { - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } HANDLE_EXCEPTION(); } } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); } zend_invalid_method_call(object, function_name); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); @@ -105503,18 +100325,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S called_scope = obj->ce; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_TMP_VAR == IS_CONST && EXPECTED(CACHED_PTR(opline->result.num) == called_scope)) { fbc = CACHED_PTR(opline->result.num + sizeof(void*)); } else { zend_object *orig_obj = obj; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - function_name = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR == IS_CONST) { + function_name = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); } /* First, locate the function. */ - fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); + fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_TMP_VAR == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL)); if (UNEXPECTED(fbc == NULL)) { if (EXPECTED(!EG(exception))) { zend_undefined_method(orig_obj->ce, Z_STR_P(function_name)); @@ -105525,7 +100347,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S } HANDLE_EXCEPTION(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && + if (IS_TMP_VAR == IS_CONST && EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE))) && EXPECTED(obj == orig_obj)) { CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc); @@ -105541,7 +100363,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S } } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); } @@ -105572,7 +100394,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_METHOD_CALL_S ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *expr_ptr, new_expr; @@ -105613,15 +100435,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ } } - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + if (IS_TMP_VAR != IS_UNUSED) { + zval *offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); zend_string *str; zend_ulong hval; add_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { if (ZEND_HANDLE_NUMERIC(str, hval)) { goto num_index; } @@ -105632,7 +100454,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ hval = Z_LVAL_P(offset); num_index: zend_hash_index_update(Z_ARRVAL_P(EX_VAR(opline->result.var)), hval, expr_ptr); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { offset = Z_REFVAL_P(offset); goto add_again; } else if (UNEXPECTED(Z_TYPE_P(offset) == IS_NULL)) { @@ -105665,7 +100487,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ zend_use_resource_as_offset(offset); hval = Z_RES_HANDLE_P(offset); goto num_index; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + } else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); str = ZSTR_EMPTY_ALLOC(); goto str_index; @@ -105683,7 +100505,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ADD_ARRAY_ELEMENT_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zval *array; uint32_t size; @@ -105698,14 +100520,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INIT_ARRAY_SPEC_CV if (opline->extended_value & ZEND_ARRAY_NOT_PACKED) { zend_hash_real_init_mixed(Z_ARRVAL_P(array)); } - ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); + ZEND_VM_TAIL_CALL(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { ZVAL_ARR(array, zend_new_array(0)); ZEND_VM_NEXT_OPCODE(); } } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -105715,7 +100537,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_CV_ SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); do { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -105727,7 +100549,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_CV_ offset_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { key = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { if (ZEND_HANDLE_NUMERIC(key, hval)) { goto num_index_dim; } @@ -105739,7 +100561,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_CV_ hval = Z_LVAL_P(offset); num_index_dim: zend_hash_index_del(ht, hval); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_TYPE_P(offset) == IS_REFERENCE)) { offset = Z_REFVAL_P(offset); goto offset_again; } else if (Z_TYPE_P(offset) == IS_DOUBLE) { @@ -105768,7 +100590,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_CV_ zend_use_resource_as_offset(offset); hval = Z_RES_HANDLE_P(offset); goto num_index_dim; - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { + } else if (IS_TMP_VAR == IS_CV && Z_TYPE_P(offset) == IS_UNDEF) { ZVAL_UNDEFINED_OP2(); key = ZSTR_EMPTY_ALLOC(); goto str_index_dim; @@ -105785,11 +100607,11 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_CV_ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { container = ZVAL_UNDEFINED_OP1(); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { offset = ZVAL_UNDEFINED_OP2(); } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { offset++; } Z_OBJ_HT_P(container)->unset_dimension(Z_OBJ_P(container), offset); @@ -105808,7 +100630,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_DIM_SPEC_CV_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -105817,7 +100639,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_CV_ SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { @@ -105834,7 +100656,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_CV_ break; } } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(offset); } else { name = zval_try_get_tmp_string(offset, &tmp_name); @@ -105842,8 +100664,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_CV_ break; } } - Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + Z_OBJ_HT_P(container)->unset_property(Z_OBJ_P(container), name, ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } } while (0); @@ -105854,7 +100676,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_OBJ_SPEC_CV_ ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -105864,7 +100686,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_ SAVE_OPLINE(); container = EX_VAR(opline->op1.var); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht; @@ -105876,17 +100698,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_ isset_again: if (EXPECTED(Z_TYPE_P(offset) == IS_STRING)) { str = Z_STR_P(offset); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { if (ZEND_HANDLE_NUMERIC(str, hval)) { goto num_index_prop; } } - value = zend_hash_find_ex(ht, str, (IS_TMP_VAR|IS_VAR) == IS_CONST); + value = zend_hash_find_ex(ht, str, IS_TMP_VAR == IS_CONST); } else if (EXPECTED(Z_TYPE_P(offset) == IS_LONG)) { hval = Z_LVAL_P(offset); num_index_prop: value = zend_hash_index_find(ht, hval); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { + } else if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(offset))) { offset = Z_REFVAL_P(offset); goto isset_again; } else { @@ -105918,7 +100740,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_ } } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + if (IS_TMP_VAR == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { offset++; } if (!(opline->extended_value & ZEND_ISEMPTY)) { @@ -105934,7 +100756,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_DIM_ ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zval *container; @@ -105944,7 +100766,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); - offset = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + offset = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if (IS_CV == IS_CONST || (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -105960,7 +100782,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP } } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(offset); } else { name = zval_try_get_tmp_string(offset, &tmp_name); @@ -105972,9 +100794,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP result = (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + Z_OBJ_HT_P(container)->has_property(Z_OBJ_P(container), name, (opline->extended_value & ZEND_ISEMPTY), ((IS_TMP_VAR == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -105985,7 +100807,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_PROP ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -105996,14 +100818,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_S SAVE_OPLINE(); key = EX_VAR(opline->op1.var); - subject = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); + subject = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { array_key_exists_array: ht = Z_ARRVAL_P(subject); result = zend_array_key_exists_fast(ht, key OPLINE_CC EXECUTE_DATA_CC); } else { - if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { + if ((IS_TMP_VAR & (IS_VAR|IS_CV)) && EXPECTED(Z_ISREF_P(subject))) { subject = Z_REFVAL_P(subject); if (EXPECTED(Z_TYPE_P(subject) == IS_ARRAY)) { goto array_key_exists_array; @@ -106019,7 +100841,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ARRAY_KEY_EXISTS_S ZEND_VM_SMART_BRANCH(result, 1); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CV_TMPVAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -106106,9 +100928,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CV_TMPV } /* Set the new yielded key */ - if ((IS_TMP_VAR|IS_VAR) != IS_UNUSED) { - zval *key = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - if (((IS_TMP_VAR|IS_VAR) & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { + if (IS_TMP_VAR != IS_UNUSED) { + zval *key = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); + if ((IS_TMP_VAR & (IS_CV|IS_VAR)) && UNEXPECTED(Z_TYPE_P(key) == IS_REFERENCE)) { key = Z_REFVAL_P(key); } ZVAL_COPY(&generator->key, key); @@ -106141,190 +100963,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_YIELD_SPEC_CV_TMPV ZEND_VM_RETURN(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = EX_VAR(opline->op1.var); - - if (0 || UNEXPECTED(0)) { - zend_refcounted *garbage = NULL; - - value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(0)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES()); - } - - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = EX_VAR(opline->op1.var); - - if (0 || UNEXPECTED(1)) { - zend_refcounted *garbage = NULL; - - value = zend_assign_to_variable_ex(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(1)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_TMP_VAR, EX_USES_STRICT_TYPES()); - } - - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_IDENTICAL_SPEC_CV_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_identical_function(op1, op2); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *op1, *op2; - bool result; - - SAVE_OPLINE(); - op1 = _get_zval_ptr_cv_deref_BP_VAR_R(opline->op1.var EXECUTE_DATA_CC); - op2 = _get_zval_ptr_var_deref(opline->op2.var EXECUTE_DATA_CC); - result = fast_is_not_identical_function(op1, op2); - - - zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); - ZEND_VM_SMART_BRANCH(result, 1); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = EX_VAR(opline->op1.var); - - if (0 || UNEXPECTED(0)) { - zend_refcounted *garbage = NULL; - - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(0)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES()); - } - - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *value; - zval *variable_ptr; - - SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); - variable_ptr = EX_VAR(opline->op1.var); - - if (0 || UNEXPECTED(1)) { - zend_refcounted *garbage = NULL; - - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(1)) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - value = zend_assign_to_variable(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES()); - } - - - /* zend_assign_to_variable() always takes care of op2, never free it! */ - - ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); -} - static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_REF_SPEC_CV_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -106548,7 +101186,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_IS_SPEC_CV_U ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper_SPEC_CV_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_EX 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -106596,6 +101234,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_UNUSED == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + if (IS_CV & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -106914,161 +101564,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_UNUSED == IS_UNUSED) { - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = NULL; - if (IS_UNUSED == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = NULL; - if (IS_UNUSED == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_UNUSED == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_UNUSED == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = NULL; - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = NULL; - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = NULL; -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_UNUSED != IS_UNUSED) { - - - } - - - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -107699,7 +102194,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_UNSET_VAR_SPEC_CV_ 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) */ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -107788,7 +102283,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ISSET_ISEMPTY_VAR_ 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_INSTANCEOF_SPEC_CV_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -108779,7 +103274,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_OP_SPEC 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -109051,13 +103546,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_R_SPEC_C SAVE_OPLINE(); container = EX_VAR(opline->op1.var); + if (IS_CV & (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 = EX_VAR(opline->op2.var); if (IS_CV != IS_CONST) { if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { fetch_dim_r_array: value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, IS_CV, 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 (IS_CV == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { goto fetch_dim_r_array; @@ -109120,6 +103619,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_IS_SPEC_ SAVE_OPLINE(); container = EX_VAR(opline->op1.var); + /* 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, EX_VAR(opline->op2.var), IS_CV OPLINE_CC EXECUTE_DATA_CC); @@ -109143,6 +103644,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_CV == IS_UNUSED) { ZEND_VM_TAIL_CALL(zend_use_undef_in_read_context_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + if (IS_CV & IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -109171,11 +103684,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_R_SPEC_C SAVE_OPLINE(); container = EX_VAR(opline->op1.var); + if (IS_CV & (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 (IS_CV == IS_CONST || (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { do { - if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { + if ((IS_CV & IS_CV) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { break; @@ -109383,6 +103900,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_IS_SPEC_ SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(opline->op1.var EXECUTE_DATA_CC); + /* Unlike FETCH_OBJ_R, this may receive references through return-by-ref + * calls using ??=, i.e. foo()->bar ??= baz. */ if (IS_CV == IS_CONST || (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) { @@ -109511,6 +104030,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_W_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } else { + if (IS_CV == IS_VAR) { + zval *op1 = EX_VAR(opline->op1.var); + if (Z_TYPE_P(op1) == IS_REFERENCE) { + zend_reference *ref = Z_REF_P(op1); + ZVAL_COPY_VALUE(op1, &ref->val); + if (GC_DELREF(ref) == 0) { + efree_size(ref, sizeof(zend_reference)); + } else { + Z_TRY_ADDREF_P(op1); + } + } + } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } } @@ -109690,7 +104221,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -109846,163 +104377,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV ZEND_VM_NEXT_OPCODE_EX(1, 2); } -/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */ -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object, *value, tmp; - zend_object *zobj; - zend_string *name, *tmp_name; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - object = EX_VAR(opline->op1.var); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - - if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (Z_ISREF_P(object) && Z_TYPE_P(Z_REFVAL_P(object)) == IS_OBJECT) { - object = Z_REFVAL_P(object); - goto assign_object; - } - zend_throw_non_object_error(object, _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC) OPLINE_CC EXECUTE_DATA_CC); - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - -assign_object: - zobj = Z_OBJ_P(object); - if (IS_CV == IS_CONST) { - if (EXPECTED(zobj->ce == CACHED_PTR(opline->extended_value))) { - void **cache_slot = CACHE_ADDR(opline->extended_value); - uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); - zval *property_val; - zend_property_info *prop_info; - - if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { - prop_info = (zend_property_info*) CACHED_PTR_EX(cache_slot + 2); - -assign_obj_simple: - property_val = OBJ_PROP(zobj, prop_offset); - if (Z_TYPE_P(property_val) != IS_UNDEF) { - if (prop_info != NULL) { - value = zend_assign_to_typed_prop(prop_info, property_val, value, &garbage EXECUTE_DATA_CC); - goto free_and_exit_assign_obj; - } else { -fast_assign_obj: - value = zend_assign_to_variable_ex(property_val, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } - } else if (EXPECTED(IS_DYNAMIC_PROPERTY_OFFSET(prop_offset))) { - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - if (UNEXPECTED(zend_lazy_object_must_init(zobj))) { - zobj = zend_lazy_object_init(zobj); - if (!zobj) { - value = &EG(uninitialized_zval); - goto free_and_exit_assign_obj; - } - } - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - rebuild_object_properties_internal(zobj); - } - if (EXPECTED(zobj->properties != NULL)) { - if (UNEXPECTED(GC_REFCOUNT(zobj->properties) > 1)) { - if (EXPECTED(!(GC_FLAGS(zobj->properties) & IS_ARRAY_IMMUTABLE))) { - GC_DELREF(zobj->properties); - } - zobj->properties = zend_array_dup(zobj->properties); - } - property_val = zend_hash_find_known_hash(zobj->properties, name); - if (property_val) { - goto fast_assign_obj; - } - } - - if (!zobj->ce->__set && (zobj->ce->ce_flags & ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES)) { - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } else if (IS_VAR != IS_TMP_VAR) { - if (Z_ISREF_P(value)) { - if (IS_VAR == IS_VAR) { - zend_reference *ref = Z_REF_P(value); - if (GC_DELREF(ref) == 0) { - ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(value)); - efree_size(ref, sizeof(zend_reference)); - value = &tmp; - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else { - value = Z_REFVAL_P(value); - Z_TRY_ADDREF_P(value); - } - } else if (IS_VAR == IS_CV) { - Z_TRY_ADDREF_P(value); - } - } - zend_hash_add_new(zobj->properties, name, value); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - goto exit_assign_obj; - } - } else { - ZEND_ASSERT(IS_HOOKED_PROPERTY_OFFSET(prop_offset)); - if (ZEND_IS_PROPERTY_HOOK_SIMPLE_WRITE(prop_offset)) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - prop_offset = prop_info->offset; - if (!ZEND_TYPE_IS_SET(prop_info->type)) { - prop_info = NULL; - } - goto assign_obj_simple; - } - /* Fall through to write_property for hooks. */ - } - } - name = Z_STR_P(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC)); - } else { - name = zval_try_get_tmp_string(_get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC), &tmp_name); - if (UNEXPECTED(!name)) { - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - goto exit_assign_obj; - } - } - - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - - value = zobj->handlers->write_property(zobj, name, value, (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL); - - if (IS_CV != IS_CONST) { - zend_tmp_string_release(tmp_name); - } - -free_and_exit_assign_obj: - if (UNEXPECTED(RETURN_VALUE_USED(opline)) && value) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value); - } - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); -exit_assign_obj: - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - - - - - /* assign_obj has two opcodes! */ - 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -110160,7 +104535,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_SPEC_CV 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -110475,161 +104850,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV ZEND_VM_NEXT_OPCODE_EX(1, 2); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - zval *object_ptr, *orig_object_ptr; - zval *value; - zval *variable_ptr; - zval *dim; - zend_refcounted *garbage = NULL; - - SAVE_OPLINE(); - orig_object_ptr = object_ptr = EX_VAR(opline->op1.var); - - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { -try_assign_dim_array: - SEPARATE_ARRAY(object_ptr); - if (IS_CV == IS_UNUSED) { - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - HashTable *ht = Z_ARRVAL_P(object_ptr); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { - GC_ADDREF(ht); - } - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { - ZVAL_DEREF(value); - } - value = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), value); - if (UNEXPECTED(value == NULL)) { - zend_cannot_add_element(); - goto assign_dim_error; - } else if (IS_VAR == IS_CV) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - } else if (IS_VAR == IS_VAR) { - zval *free_op_data = EX_VAR((opline+1)->op1.var); - if (Z_ISREF_P(free_op_data)) { - if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - zval_ptr_dtor_nogc(free_op_data); - } - } else if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - Z_ADDREF_P(value); - } - } - } else { - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CONST) { - variable_ptr = zend_fetch_dimension_address_inner_W_CONST(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } else { - variable_ptr = zend_fetch_dimension_address_inner_W(Z_ARRVAL_P(object_ptr), dim EXECUTE_DATA_CC); - } - if (UNEXPECTED(variable_ptr == NULL)) { - goto assign_dim_error; - } - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - value = zend_assign_to_variable_ex(variable_ptr, value, IS_VAR, EX_USES_STRICT_TYPES(), &garbage); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), value); - } - if (garbage) { - GC_DTOR_NO_REF(garbage); - } - } else { - if (EXPECTED(Z_ISREF_P(object_ptr))) { - object_ptr = Z_REFVAL_P(object_ptr); - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { - goto try_assign_dim_array; - } - } - if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { - zend_object *obj = Z_OBJ_P(object_ptr); - - GC_ADDREF(obj); - dim = EX_VAR(opline->op2.var); - if (IS_CV == IS_CV && UNEXPECTED(Z_ISUNDEF_P(dim))) { - dim = ZVAL_UNDEFINED_OP2(); - } else if (IS_CV == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - if (IS_VAR == IS_CV && UNEXPECTED(Z_ISUNDEF_P(value))) { - value = zval_undefined_cv((opline+1)->op1.var EXECUTE_DATA_CC); - } else if (IS_VAR & (IS_CV|IS_VAR)) { - ZVAL_DEREF(value); - } - - zend_assign_to_object_dim(obj, dim, value OPLINE_CC EXECUTE_DATA_CC); - - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(GC_DELREF(obj) == 0)) { - zend_objects_store_del(obj); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { - if (IS_CV == IS_UNUSED) { - zend_use_new_element_for_string(); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - dim = EX_VAR(opline->op2.var); - value = _get_zval_ptr_var((opline+1)->op1.var EXECUTE_DATA_CC); - zend_assign_to_string_offset(object_ptr, dim, value OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - } - } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { - if (Z_ISREF_P(orig_object_ptr) - && ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr)) - && !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) { - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - UNDEF_RESULT(); - } else { - HashTable *ht = zend_new_array(8); - uint8_t old_type = Z_TYPE_P(object_ptr); - - ZVAL_ARR(object_ptr, ht); - if (UNEXPECTED(old_type == IS_FALSE)) { - GC_ADDREF(ht); - zend_false_to_array_deprecated(); - if (UNEXPECTED(GC_DELREF(ht) == 0)) { - zend_array_destroy(ht); - goto assign_dim_error; - } - } - goto try_assign_dim_array; - } - } else { - zend_use_scalar_as_array(); - dim = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); -assign_dim_error: - zval_ptr_dtor_nogc(EX_VAR((opline+1)->op1.var)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - } - } - if (IS_CV != IS_UNUSED) { - - - } - - - /* assign_dim has two opcodes! */ - ZEND_VM_NEXT_OPCODE_EX(1, 2); -} - static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -110926,7 +105146,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -110965,7 +105185,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_ASSIGN_OBJ_REF_SPE 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) */ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FAST_CONCAT_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -112203,7 +106423,7 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_fetch_static_prop_helper_ 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) */ static zend_never_inline ZEND_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_cannot_pass_by_ref_helper_SPEC_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX uint32_t _arg_num, zval *_arg) { USE_OPLINE @@ -112427,7 +106647,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX z ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } -static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX int type) +static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX zend_fetch_var_address_helper_SPEC_TMP_UNUSED_TAILCALL(ZEND_OPCODE_HANDLER_ARGS_EX int type) { USE_OPLINE zval *varname; @@ -112436,15 +106656,15 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX z HashTable *target_symbol_table; SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); + varname = _get_zval_ptr_tmp(opline->op1.var EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(varname); } else if (EXPECTED(Z_TYPE_P(varname) == IS_STRING)) { name = Z_STR_P(varname); tmp_name = NULL; } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { + if (IS_TMP_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(varname) == IS_UNDEF)) { ZVAL_UNDEFINED_OP1(); } name = zval_try_get_tmp_string(varname, &tmp_name); @@ -112458,12 +106678,12 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX z } target_symbol_table = zend_get_target_symbol_table(opline->extended_value EXECUTE_DATA_CC); - retval = zend_hash_find_ex(target_symbol_table, name, (IS_TMP_VAR|IS_VAR) == IS_CONST); + retval = zend_hash_find_ex(target_symbol_table, name, IS_TMP_VAR == IS_CONST); if (retval == NULL) { if (UNEXPECTED(zend_string_equals(name, ZSTR_KNOWN(ZEND_STR_THIS)))) { fetch_this: zend_fetch_this_var(type OPLINE_CC EXECUTE_DATA_CC); - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -112473,7 +106693,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX z } else if (type == BP_VAR_IS || type == BP_VAR_UNSET) { retval = &EG(uninitialized_zval); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { + if (IS_TMP_VAR == IS_CV) { /* Keep name alive in case an error handler tries to free it. */ zend_string_addref(name); } @@ -112484,7 +106704,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX z } else { retval = &EG(uninitialized_zval); } - if ((IS_TMP_VAR|IS_VAR) == IS_CV) { + if (IS_TMP_VAR == IS_CV) { zend_string_release(name); } } @@ -112515,7 +106735,7 @@ static zend_never_inline ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV_EX z zval_ptr_dtor_nogc(EX_VAR(opline->op1.var)); } - if ((IS_TMP_VAR|IS_VAR) != IS_CONST) { + if (IS_TMP_VAR != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -112756,28 +106976,28 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_DIV_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_DIV_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_DIV_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_DIV_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_DIV_SPEC_CONST_CV_LABEL, - (void*)&&ZEND_DIV_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_DIV_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_DIV_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_DIV_SPEC_TMP_CONST_LABEL, + (void*)&&ZEND_DIV_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_DIV_SPEC_TMP_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_DIV_SPEC_TMPVAR_CV_LABEL, - (void*)&&ZEND_DIV_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_DIV_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_DIV_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_DIV_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_DIV_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_DIV_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_DIV_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_DIV_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_DIV_SPEC_CV_CV_LABEL, (void*)&&ZEND_MOD_SPEC_CONST_CONST_LABEL, @@ -112856,28 +107076,28 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_SR_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_CONCAT_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_CONCAT_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_CONCAT_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_CONCAT_SPEC_CONST_CV_LABEL, - (void*)&&ZEND_CONCAT_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_CONCAT_SPEC_TMP_CONST_LABEL, + (void*)&&ZEND_CONCAT_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_CONCAT_SPEC_TMP_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_CONCAT_SPEC_TMPVAR_CV_LABEL, - (void*)&&ZEND_CONCAT_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_CONCAT_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_CONCAT_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_CONCAT_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_CONCAT_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_CONCAT_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_CONCAT_SPEC_CV_CV_LABEL, (void*)&&ZEND_BW_OR_SPEC_CONST_CONST_LABEL, @@ -112956,28 +107176,28 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_LABEL, (void*)&&ZEND_POW_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_POW_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_POW_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_POW_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_POW_SPEC_CONST_CV_LABEL, - (void*)&&ZEND_POW_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_POW_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_POW_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_POW_SPEC_TMP_CONST_LABEL, + (void*)&&ZEND_POW_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_POW_SPEC_TMP_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_POW_SPEC_TMPVAR_CV_LABEL, - (void*)&&ZEND_POW_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_POW_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_POW_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_POW_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_POW_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_POW_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_POW_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_POW_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_POW_SPEC_CV_CV_LABEL, (void*)&&ZEND_BW_NOT_SPEC_CONST_LABEL, @@ -112986,8 +107206,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BW_NOT_SPEC_TMPVARCV_LABEL, (void*)&&ZEND_BOOL_NOT_SPEC_CONST_LABEL, - (void*)&&ZEND_BOOL_NOT_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_BOOL_NOT_SPEC_TMPVAR_LABEL, + (void*)&&ZEND_BOOL_NOT_SPEC_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BOOL_NOT_SPEC_CV_LABEL, (void*)&&ZEND_BOOL_XOR_SPEC_CONST_CONST_LABEL, @@ -112995,14 +107215,14 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_BOOL_XOR_SPEC_TMP_CONST_LABEL, + (void*)&&ZEND_BOOL_XOR_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113011,8 +107231,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BOOL_XOR_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_BOOL_XOR_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_BOOL_XOR_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_BOOL_XOR_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BOOL_XOR_SPEC_CV_CV_LABEL, (void*)&&ZEND_IS_IDENTICAL_SPEC_CONST_CONST_LABEL, @@ -113025,9 +107245,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_IDENTICAL_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_IS_IDENTICAL_SPEC_VAR_TMP_LABEL, - (void*)&&ZEND_IS_IDENTICAL_SPEC_VAR_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113037,7 +107257,7 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_IS_IDENTICAL_SPEC_CV_CONST_LABEL, (void*)&&ZEND_IS_IDENTICAL_SPEC_CV_TMP_LABEL, - (void*)&&ZEND_IS_IDENTICAL_SPEC_CV_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_IS_IDENTICAL_SPEC_CV_CV_LABEL, (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST_LABEL, @@ -113050,9 +107270,9 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_LABEL, - (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113062,7 +107282,7 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_LABEL, (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_LABEL, - (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_LABEL, (void*)&&ZEND_IS_EQUAL_SPEC_CONST_CONST_LABEL, @@ -113080,30 +107300,30 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_LABEL, + (void*)&&ZEND_IS_EQUAL_SPEC_TMP_CONST_LABEL, + (void*)&&ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_EQUAL_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ_LABEL, + (void*)&&ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113128,12 +107348,12 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_IS_EQUAL_SPEC_CV_CONST_LABEL, (void*)&&ZEND_IS_EQUAL_SPEC_CV_CONST_JMPZ_LABEL, (void*)&&ZEND_IS_EQUAL_SPEC_CV_CONST_JMPNZ_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ_LABEL, - (void*)&&ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ_LABEL, + (void*)&&ZEND_IS_EQUAL_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ_LABEL, + (void*)&&ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113155,30 +107375,30 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113203,12 +107423,12 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPZ_LABEL, (void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPNZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ_LABEL, - (void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ_LABEL, + (void*)&&ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113389,8 +107609,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_USED_LABEL, (void*)&&ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED_LABEL, (void*)&&ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED_LABEL, - (void*)&&ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED_LABEL, - (void*)&&ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_UNUSED_LABEL, @@ -113409,8 +107629,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_USED_LABEL, (void*)&&ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_LABEL, (void*)&&ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_LABEL, - (void*)&&ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED_LABEL, - (void*)&&ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSED_LABEL, @@ -113467,27 +107687,27 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_LABEL, + (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST_LABEL, + (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CONST_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CONST_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113517,27 +107737,27 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_LABEL, + (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST_LABEL, + (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113592,19 +107812,19 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113612,24 +107832,24 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113637,24 +107857,24 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113662,12 +107882,12 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_LABEL, (void*)&&ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CONST_LABEL, (void*)&&ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_TMP_LABEL, - (void*)&&ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113681,8 +107901,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OP_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_ASSIGN_OP_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OP_SPEC_VAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113691,8 +107911,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OP_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_ASSIGN_OP_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_ASSIGN_OP_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_ASSIGN_OP_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OP_SPEC_CV_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113706,8 +107926,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_LABEL, (void*)&&ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113716,8 +107936,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113731,18 +107951,18 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_LABEL, (void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV_LABEL, (void*)&&ZEND_ASSIGN_STATIC_PROP_OP_SPEC_LABEL, @@ -113833,14 +108053,14 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113858,14 +108078,14 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113883,14 +108103,14 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113936,30 +108156,30 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_POST_INC_STATIC_PROP_SPEC_LABEL, (void*)&&ZEND_JMP_SPEC_LABEL, (void*)&&ZEND_JMPZ_SPEC_CONST_LABEL, - (void*)&&ZEND_JMPZ_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_JMPZ_SPEC_TMPVAR_LABEL, + (void*)&&ZEND_JMPZ_SPEC_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_JMPZ_SPEC_CV_LABEL, (void*)&&ZEND_JMPNZ_SPEC_CONST_LABEL, - (void*)&&ZEND_JMPNZ_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_JMPNZ_SPEC_TMPVAR_LABEL, + (void*)&&ZEND_JMPNZ_SPEC_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_JMPNZ_SPEC_CV_LABEL, (void*)&&ZEND_JMPZ_EX_SPEC_CONST_LABEL, - (void*)&&ZEND_JMPZ_EX_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_JMPZ_EX_SPEC_TMPVAR_LABEL, + (void*)&&ZEND_JMPZ_EX_SPEC_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_JMPZ_EX_SPEC_CV_LABEL, (void*)&&ZEND_JMPNZ_EX_SPEC_CONST_LABEL, - (void*)&&ZEND_JMPNZ_EX_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_JMPNZ_EX_SPEC_TMPVAR_LABEL, + (void*)&&ZEND_JMPNZ_EX_SPEC_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_JMPNZ_EX_SPEC_CV_LABEL, - (void*)&&ZEND_CASE_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_CASE_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_CASE_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_CASE_SPEC_TMP_CONST_LABEL, + (void*)&&ZEND_CASE_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_CASE_SPEC_TMPVAR_CV_LABEL, + (void*)&&ZEND_CASE_SPEC_TMP_CV_LABEL, (void*)&&ZEND_CHECK_VAR_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST_LABEL, (void*)&&ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST_LABEL, @@ -113973,52 +108193,52 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_CAST_SPEC_CONST_LABEL, (void*)&&ZEND_CAST_SPEC_TMP_LABEL, - (void*)&&ZEND_CAST_SPEC_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_CAST_SPEC_CV_LABEL, (void*)&&ZEND_BOOL_SPEC_CONST_LABEL, - (void*)&&ZEND_BOOL_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_BOOL_SPEC_TMPVAR_LABEL, + (void*)&&ZEND_BOOL_SPEC_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_BOOL_SPEC_CV_LABEL, (void*)&&ZEND_FAST_CONCAT_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_FAST_CONCAT_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FAST_CONCAT_SPEC_CONST_CV_LABEL, - (void*)&&ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_FAST_CONCAT_SPEC_TMP_CONST_LABEL, + (void*)&&ZEND_FAST_CONCAT_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_FAST_CONCAT_SPEC_TMP_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_LABEL, - (void*)&&ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FAST_CONCAT_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_FAST_CONCAT_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FAST_CONCAT_SPEC_CV_CV_LABEL, (void*)&&ZEND_ROPE_INIT_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_LABEL, - (void*)&&ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_ROPE_INIT_SPEC_UNUSED_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ROPE_INIT_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_ROPE_ADD_SPEC_TMP_CONST_LABEL, - (void*)&&ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_LABEL, - (void*)&&ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_LABEL, + (void*)&&ZEND_ROPE_ADD_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ROPE_ADD_SPEC_TMP_CV_LABEL, (void*)&&ZEND_ROPE_END_SPEC_TMP_CONST_LABEL, - (void*)&&ZEND_ROPE_END_SPEC_TMP_TMPVAR_LABEL, - (void*)&&ZEND_ROPE_END_SPEC_TMP_TMPVAR_LABEL, + (void*)&&ZEND_ROPE_END_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ROPE_END_SPEC_TMP_CV_LABEL, (void*)&&ZEND_BEGIN_SILENCE_SPEC_LABEL, @@ -114033,8 +108253,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_RETURN_SPEC_OBSERVER_LABEL, (void*)&&ZEND_RETURN_SPEC_TMP_LABEL, (void*)&&ZEND_RETURN_SPEC_OBSERVER_LABEL, - (void*)&&ZEND_RETURN_SPEC_VAR_LABEL, - (void*)&&ZEND_RETURN_SPEC_OBSERVER_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_RETURN_SPEC_CV_LABEL, @@ -114149,43 +108369,43 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_LABEL, (void*)&&ZEND_FREE_SPEC_TMPVAR_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_INIT_ARRAY_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_CONST_CV_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_TMP_CONST_LABEL, - (void*)&&ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_LABEL, - (void*)&&ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_LABEL, + (void*)&&ZEND_INIT_ARRAY_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_TMP_CV_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_INIT_ARRAY_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_VAR_CV_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_LABEL, - (void*)&&ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_INIT_ARRAY_SPEC_UNUSED_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_INIT_ARRAY_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_INIT_ARRAY_SPEC_CV_CV_LABEL, (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_LABEL, (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_LABEL, (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_LABEL, - (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_LABEL, - (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_LABEL, + (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_LABEL, (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_LABEL, (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_LABEL, (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114194,18 +108414,18 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_LABEL, (void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_CONST_LABEL, (void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_LABEL, - (void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_LABEL, - (void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_LABEL, + (void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_TMP_LABEL, (void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_CV_LABEL, (void*)&&ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_LABEL, (void*)&&ZEND_UNSET_VAR_SPEC_CONST_UNUSED_LABEL, @@ -114224,8 +108444,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_UNSET_DIM_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_UNSET_DIM_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_UNSET_DIM_SPEC_VAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114234,8 +108454,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_UNSET_DIM_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_UNSET_DIM_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_UNSET_DIM_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_UNSET_DIM_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_UNSET_DIM_SPEC_CV_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114249,44 +108469,44 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_UNSET_OBJ_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_UNSET_OBJ_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_UNSET_OBJ_SPEC_VAR_CV_LABEL, (void*)&&ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_LABEL, - (void*)&&ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_UNSET_OBJ_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_UNSET_OBJ_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_UNSET_OBJ_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_UNSET_OBJ_SPEC_CV_CV_LABEL, (void*)&&ZEND_FE_RESET_R_SPEC_CONST_LABEL, (void*)&&ZEND_FE_RESET_R_SPEC_TMP_LABEL, - (void*)&&ZEND_FE_RESET_R_SPEC_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FE_RESET_R_SPEC_CV_LABEL, - (void*)&&ZEND_FE_FETCH_R_SPEC_VAR_LABEL, + (void*)&&ZEND_FE_FETCH_R_SPEC_TMP_LABEL, (void*)&&ZEND_FETCH_R_SPEC_CONST_UNUSED_LABEL, - (void*)&&ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_LABEL, - (void*)&&ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_LABEL, + (void*)&&ZEND_FETCH_R_SPEC_TMP_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_R_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_FETCH_DIM_R_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_R_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_R_SPEC_CONST_CV_LABEL, (void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114295,38 +108515,38 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_R_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_R_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_R_SPEC_CV_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_R_SPEC_CONST_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_R_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_R_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_R_SPEC_CV_CV_LABEL, (void*)&&ZEND_FETCH_W_SPEC_CONST_UNUSED_LABEL, - (void*)&&ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_LABEL, - (void*)&&ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_LABEL, + (void*)&&ZEND_FETCH_W_SPEC_TMP_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_W_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114340,8 +108560,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_W_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_W_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_LABEL, (void*)&&ZEND_FETCH_DIM_W_SPEC_VAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114350,8 +108570,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_W_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_W_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_FETCH_DIM_W_SPEC_CV_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114365,23 +108585,23 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_W_SPEC_VAR_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_W_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_W_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_W_SPEC_CV_CV_LABEL, (void*)&&ZEND_FETCH_RW_SPEC_CONST_UNUSED_LABEL, - (void*)&&ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_LABEL, - (void*)&&ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_LABEL, + (void*)&&ZEND_FETCH_RW_SPEC_TMP_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_RW_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114395,8 +108615,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_LABEL, (void*)&&ZEND_FETCH_DIM_RW_SPEC_VAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114405,8 +108625,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_RW_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_RW_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_FETCH_DIM_RW_SPEC_CV_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114420,38 +108640,38 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_RW_SPEC_CV_CV_LABEL, (void*)&&ZEND_FETCH_IS_SPEC_CONST_UNUSED_LABEL, - (void*)&&ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_LABEL, - (void*)&&ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_LABEL, + (void*)&&ZEND_FETCH_IS_SPEC_TMP_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_IS_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_IS_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_IS_SPEC_CONST_CV_LABEL, (void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114460,53 +108680,53 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_IS_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_IS_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_IS_SPEC_CV_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_IS_SPEC_CV_CV_LABEL, (void*)&&ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED_LABEL, - (void*)&&ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_LABEL, - (void*)&&ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_LABEL, + (void*)&&ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_LABEL, (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_LABEL, (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_LABEL, (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_LABEL, (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_LABEL, (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114515,38 +108735,38 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_LABEL, (void*)&&ZEND_FETCH_UNSET_SPEC_CONST_UNUSED_LABEL, - (void*)&&ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_LABEL, - (void*)&&ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_LABEL, + (void*)&&ZEND_FETCH_UNSET_SPEC_TMP_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_UNSET_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114560,8 +108780,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114570,8 +108790,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114585,33 +108805,33 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_LABEL, (void*)&&ZEND_FETCH_LIST_R_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_LIST_R_SPEC_CONST_CV_LABEL, (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_LABEL, - (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_LABEL, (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_LABEL, - (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114620,8 +108840,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_LABEL, - (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_LABEL, (void*)&&ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_LABEL, @@ -114647,18 +108867,18 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_CATCH_SPEC_CONST_LABEL, (void*)&&ZEND_THROW_SPEC_CONST_LABEL, - (void*)&&ZEND_THROW_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_THROW_SPEC_TMPVAR_LABEL, + (void*)&&ZEND_THROW_SPEC_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_THROW_SPEC_CV_LABEL, (void*)&&ZEND_FETCH_CLASS_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_CLASS_SPEC_UNUSED_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED_LABEL, (void*)&&ZEND_FETCH_CLASS_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_CLONE_SPEC_CONST_LABEL, - (void*)&&ZEND_CLONE_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_CLONE_SPEC_TMPVAR_LABEL, + (void*)&&ZEND_CLONE_SPEC_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_CLONE_SPEC_UNUSED_LABEL, (void*)&&ZEND_CLONE_SPEC_CV_LABEL, (void*)&&ZEND_RETURN_BY_REF_SPEC_CONST_LABEL, @@ -114672,33 +108892,33 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_RETURN_BY_REF_SPEC_CV_LABEL, (void*)&&ZEND_RETURN_BY_REF_SPEC_OBSERVER_LABEL, (void*)&&ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_METHOD_CALL_SPEC_CONST_CV_LABEL, - (void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_LABEL, + (void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_LABEL, - (void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_LABEL, - (void*)&&ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_METHOD_CALL_SPEC_CV_CV_LABEL, (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_LABEL, (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114707,13 +108927,13 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_LABEL, (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_LABEL, (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_LABEL, - (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED_LABEL, (void*)&&ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114722,33 +108942,33 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_LABEL, + (void*)&&ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST_LABEL, + (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_LABEL, (void*)&&ZEND_SEND_VAL_EX_SPEC_CONST_CONST_LABEL, @@ -114827,25 +109047,25 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_SEND_VAR_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_USER_CALL_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_INIT_USER_CALL_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_USER_CALL_SPEC_CONST_CV_LABEL, (void*)&&ZEND_SEND_ARRAY_SPEC_LABEL, (void*)&&ZEND_SEND_USER_SPEC_CONST_LABEL, (void*)&&ZEND_SEND_USER_SPEC_TMP_LABEL, - (void*)&&ZEND_SEND_USER_SPEC_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_SEND_USER_SPEC_CV_LABEL, (void*)&&ZEND_STRLEN_SPEC_CONST_LABEL, - (void*)&&ZEND_STRLEN_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_STRLEN_SPEC_TMPVAR_LABEL, + (void*)&&ZEND_STRLEN_SPEC_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_STRLEN_SPEC_CV_LABEL, (void*)&&ZEND_DEFINED_SPEC_CONST_LABEL, (void*)&&ZEND_TYPE_CHECK_SPEC_CONST_LABEL, - (void*)&&ZEND_TYPE_CHECK_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_TYPE_CHECK_SPEC_TMPVAR_LABEL, + (void*)&&ZEND_TYPE_CHECK_SPEC_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_TYPE_CHECK_SPEC_CV_LABEL, (void*)&&ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED_LABEL, @@ -114861,8 +109081,8 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_FE_FETCH_RW_SPEC_VAR_LABEL, (void*)&&ZEND_FE_FREE_SPEC_TMPVAR_LABEL, (void*)&&ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_LABEL, - (void*)&&ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_LABEL, + (void*)&&ZEND_INIT_DYNAMIC_CALL_SPEC_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_INIT_DYNAMIC_CALL_SPEC_CV_LABEL, (void*)&&ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_LABEL, @@ -114888,18 +109108,18 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_PRE_INC_OBJ_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_PRE_INC_OBJ_SPEC_VAR_CV_LABEL, (void*)&&ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_LABEL, - (void*)&&ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_PRE_INC_OBJ_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_PRE_INC_OBJ_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_PRE_INC_OBJ_SPEC_CV_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114913,23 +109133,23 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_POST_INC_OBJ_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_POST_INC_OBJ_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_POST_INC_OBJ_SPEC_VAR_CV_LABEL, (void*)&&ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_LABEL, - (void*)&&ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_POST_INC_OBJ_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_POST_INC_OBJ_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_POST_INC_OBJ_SPEC_CV_CV_LABEL, (void*)&&ZEND_ECHO_SPEC_CONST_LABEL, - (void*)&&ZEND_ECHO_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_ECHO_SPEC_TMPVAR_LABEL, + (void*)&&ZEND_ECHO_SPEC_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ECHO_SPEC_CV_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114938,15 +109158,15 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_LABEL, + (void*)&&ZEND_INSTANCEOF_SPEC_TMP_CONST_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_INSTANCEOF_SPEC_TMP_VAR_LABEL, + (void*)&&ZEND_INSTANCEOF_SPEC_TMP_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_LABEL, - (void*)&&ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_LABEL, - (void*)&&ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -114972,28 +109192,28 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_DECLARE_ANON_CLASS_SPEC_LABEL, (void*)&&ZEND_ADD_ARRAY_UNPACK_SPEC_LABEL, (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_LABEL, + (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_LABEL, (void*)&&ZEND_HANDLE_EXCEPTION_SPEC_LABEL, @@ -115001,49 +109221,49 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_ASSERT_CHECK_SPEC_LABEL, (void*)&&ZEND_JMP_SET_SPEC_CONST_LABEL, (void*)&&ZEND_JMP_SET_SPEC_TMP_LABEL, - (void*)&&ZEND_JMP_SET_SPEC_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_JMP_SET_SPEC_CV_LABEL, (void*)&&ZEND_UNSET_CV_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET_LABEL, (void*)&&ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY_LABEL, (void*)&&ZEND_FETCH_LIST_W_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_LIST_W_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_LIST_W_SPEC_VAR_CV_LABEL, (void*)&&ZEND_SEPARATE_SPEC_VAR_UNUSED_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR_LABEL, + (void*)&&ZEND_FETCH_CLASS_NAME_SPEC_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_FETCH_CLASS_NAME_SPEC_UNUSED_LABEL, (void*)&&ZEND_FETCH_CLASS_NAME_SPEC_CV_LABEL, (void*)&&ZEND_CALL_TRAMPOLINE_SPEC_LABEL, (void*)&&ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_LABEL, (void*)&&ZEND_DISCARD_EXCEPTION_SPEC_LABEL, (void*)&&ZEND_YIELD_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_YIELD_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_YIELD_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_YIELD_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_YIELD_SPEC_CONST_UNUSED_LABEL, (void*)&&ZEND_YIELD_SPEC_CONST_CV_LABEL, (void*)&&ZEND_YIELD_SPEC_TMP_CONST_LABEL, - (void*)&&ZEND_YIELD_SPEC_TMP_TMPVAR_LABEL, - (void*)&&ZEND_YIELD_SPEC_TMP_TMPVAR_LABEL, + (void*)&&ZEND_YIELD_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_YIELD_SPEC_TMP_UNUSED_LABEL, (void*)&&ZEND_YIELD_SPEC_TMP_CV_LABEL, (void*)&&ZEND_YIELD_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_YIELD_SPEC_VAR_TMPVAR_LABEL, - (void*)&&ZEND_YIELD_SPEC_VAR_TMPVAR_LABEL, + (void*)&&ZEND_YIELD_SPEC_VAR_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_YIELD_SPEC_VAR_UNUSED_LABEL, (void*)&&ZEND_YIELD_SPEC_VAR_CV_LABEL, (void*)&&ZEND_YIELD_SPEC_UNUSED_CONST_LABEL, - (void*)&&ZEND_YIELD_SPEC_UNUSED_TMPVAR_LABEL, - (void*)&&ZEND_YIELD_SPEC_UNUSED_TMPVAR_LABEL, + (void*)&&ZEND_YIELD_SPEC_UNUSED_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_YIELD_SPEC_UNUSED_UNUSED_LABEL, (void*)&&ZEND_YIELD_SPEC_UNUSED_CV_LABEL, (void*)&&ZEND_YIELD_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_YIELD_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_YIELD_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_YIELD_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_YIELD_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_YIELD_SPEC_CV_CV_LABEL, (void*)&&ZEND_GENERATOR_RETURN_SPEC_CONST_LABEL, @@ -115061,40 +109281,40 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_RECV_VARIADIC_SPEC_UNUSED_LABEL, (void*)&&ZEND_SEND_UNPACK_SPEC_LABEL, (void*)&&ZEND_YIELD_FROM_SPEC_CONST_LABEL, - (void*)&&ZEND_YIELD_FROM_SPEC_TMPVAR_LABEL, - (void*)&&ZEND_YIELD_FROM_SPEC_TMPVAR_LABEL, + (void*)&&ZEND_YIELD_FROM_SPEC_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_YIELD_FROM_SPEC_CV_LABEL, (void*)&&ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_LABEL, (void*)&&ZEND_BIND_GLOBAL_SPEC_CV_CONST_LABEL, (void*)&&ZEND_COALESCE_SPEC_CONST_LABEL, (void*)&&ZEND_COALESCE_SPEC_TMP_LABEL, - (void*)&&ZEND_COALESCE_SPEC_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_COALESCE_SPEC_CV_LABEL, (void*)&&ZEND_SPACESHIP_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_SPACESHIP_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_SPACESHIP_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_SPACESHIP_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_SPACESHIP_SPEC_CONST_CV_LABEL, - (void*)&&ZEND_SPACESHIP_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_SPACESHIP_SPEC_TMP_CONST_LABEL, + (void*)&&ZEND_SPACESHIP_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_SPACESHIP_SPEC_TMP_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_SPACESHIP_SPEC_TMPVAR_CV_LABEL, - (void*)&&ZEND_SPACESHIP_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_SPACESHIP_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_SPACESHIP_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_SPACESHIP_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_SPACESHIP_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_SPACESHIP_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_SPACESHIP_SPEC_CV_CV_LABEL, (void*)&&ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED_LABEL, @@ -115157,48 +109377,48 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_IN_ARRAY_SPEC_CONST_CONST_LABEL, (void*)&&ZEND_IN_ARRAY_SPEC_TMP_CONST_LABEL, - (void*)&&ZEND_IN_ARRAY_SPEC_VAR_CONST_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_IN_ARRAY_SPEC_CV_CONST_LABEL, (void*)&&ZEND_COUNT_SPEC_CONST_UNUSED_LABEL, - (void*)&&ZEND_COUNT_SPEC_TMPVAR_UNUSED_LABEL, - (void*)&&ZEND_COUNT_SPEC_TMPVAR_UNUSED_LABEL, + (void*)&&ZEND_COUNT_SPEC_TMP_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_COUNT_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_GET_CLASS_SPEC_CONST_UNUSED_LABEL, - (void*)&&ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED_LABEL, - (void*)&&ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED_LABEL, + (void*)&&ZEND_GET_CLASS_SPEC_TMP_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_GET_CLASS_SPEC_UNUSED_UNUSED_LABEL, (void*)&&ZEND_GET_CLASS_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED_LABEL, (void*)&&ZEND_GET_TYPE_SPEC_CONST_UNUSED_LABEL, (void*)&&ZEND_GET_TYPE_SPEC_TMP_UNUSED_LABEL, - (void*)&&ZEND_GET_TYPE_SPEC_VAR_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_GET_TYPE_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR_LABEL, - (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR_LABEL, + (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV_LABEL, - (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_LABEL, + (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST_LABEL, + (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV_LABEL, - (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST_LABEL, - (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_LABEL, - (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST_LABEL, - (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR_LABEL, - (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR_LABEL, + (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_LABEL, (void*)&&ZEND_MATCH_SPEC_CONST_CONST_LABEL, @@ -115206,31 +109426,11 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_MATCH_SPEC_TMPVARCV_CONST_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_MATCH_SPEC_TMPVARCV_CONST_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_CASE_STRICT_SPEC_TMP_CONST_LABEL, (void*)&&ZEND_CASE_STRICT_SPEC_TMP_TMP_LABEL, - (void*)&&ZEND_CASE_STRICT_SPEC_TMP_VAR_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_CASE_STRICT_SPEC_TMP_CV_LABEL, - (void*)&&ZEND_CASE_STRICT_SPEC_VAR_CONST_LABEL, - (void*)&&ZEND_CASE_STRICT_SPEC_VAR_TMP_LABEL, - (void*)&&ZEND_CASE_STRICT_SPEC_VAR_VAR_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_CASE_STRICT_SPEC_VAR_CV_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, + (void*)&&ZEND_CASE_STRICT_SPEC_TMP_CV_LABEL, (void*)&&ZEND_MATCH_ERROR_SPEC_CONST_UNUSED_LABEL, (void*)&&ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_LABEL, (void*)&&ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_LABEL, @@ -115238,7 +109438,7 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_LABEL, (void*)&&ZEND_JMP_NULL_SPEC_CONST_LABEL, (void*)&&ZEND_JMP_NULL_SPEC_TMP_LABEL, - (void*)&&ZEND_JMP_NULL_SPEC_VAR_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_JMP_NULL_SPEC_CV_LABEL, (void*)&&ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_LABEL, @@ -115257,11 +109457,12 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_JMP_FRAMELESS_SPEC_CONST_LABEL, (void*)&&ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_LABEL, (void*)&&ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST_LABEL, + (void*)&&ZEND_DEREF_SPEC_VAR_UNUSED_LABEL, (void*)&&ZEND_INIT_FCALL_OFFSET_SPEC_CONST_LABEL, (void*)&&ZEND_RECV_NOTYPE_SPEC_LABEL, (void*)&&ZEND_NULL_LABEL, - (void*)&&ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED_LABEL, - (void*)&&ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED_LABEL, + (void*)&&ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED_LABEL, + (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_NULL_LABEL, (void*)&&ZEND_COUNT_ARRAY_SPEC_CV_UNUSED_LABEL, (void*)&&ZEND_JMP_FORWARD_SPEC_LABEL, @@ -116269,11 +110470,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR) - ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR) - HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV): VM_TRACE(ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV) ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -116666,10 +110862,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_RECV_INIT_SPEC_CONST) HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR): - VM_TRACE(ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) - ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) + HYBRID_CASE(ZEND_INIT_DYNAMIC_CALL_SPEC_TMP): + VM_TRACE(ZEND_INIT_DYNAMIC_CALL_SPEC_TMP) + ZEND_INIT_DYNAMIC_CALL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INIT_DYNAMIC_CALL_SPEC_TMP) HYBRID_BREAK(); HYBRID_CASE(ZEND_RECV_SPEC_UNUSED): VM_TRACE(ZEND_RECV_SPEC_UNUSED) @@ -117415,110 +111611,110 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) HYBRID_BREAK(); - HYBRID_CASE(ZEND_DIV_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_DIV_SPEC_CONST_TMPVAR) - ZEND_DIV_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_DIV_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POW_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_POW_SPEC_CONST_TMPVAR) - ZEND_POW_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_POW_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CONCAT_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_CONCAT_SPEC_CONST_TMPVAR) - ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_CONCAT_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SPACESHIP_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_SPACESHIP_SPEC_CONST_TMPVAR) - ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) - ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) - ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) - ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) - ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) - ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR) - ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) - ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) - ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) - ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR) - ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR) - ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) - ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_YIELD_SPEC_CONST_TMPVAR): - VM_TRACE(ZEND_YIELD_SPEC_CONST_TMPVAR) - ZEND_YIELD_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_YIELD_SPEC_CONST_TMPVAR) + HYBRID_CASE(ZEND_DIV_SPEC_CONST_TMP): + VM_TRACE(ZEND_DIV_SPEC_CONST_TMP) + ZEND_DIV_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_DIV_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POW_SPEC_CONST_TMP): + VM_TRACE(ZEND_POW_SPEC_CONST_TMP) + ZEND_POW_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_POW_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CONCAT_SPEC_CONST_TMP): + VM_TRACE(ZEND_CONCAT_SPEC_CONST_TMP) + ZEND_CONCAT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_CONCAT_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SPACESHIP_SPEC_CONST_TMP): + VM_TRACE(ZEND_SPACESHIP_SPEC_CONST_TMP) + ZEND_SPACESHIP_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_CONST_TMP): + VM_TRACE(ZEND_FETCH_DIM_R_SPEC_CONST_TMP) + ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_R_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_CONST_TMP): + VM_TRACE(ZEND_FETCH_DIM_IS_SPEC_CONST_TMP) + ZEND_FETCH_DIM_IS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_IS_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP): + VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP) + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_CONST_TMP): + VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_CONST_TMP) + ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_R_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP): + VM_TRACE(ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP) + ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP): + VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP) + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_CONST_TMP): + VM_TRACE(ZEND_FETCH_LIST_R_SPEC_CONST_TMP) + ZEND_FETCH_LIST_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_LIST_R_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_CONST_TMP): + VM_TRACE(ZEND_FAST_CONCAT_SPEC_CONST_TMP) + ZEND_FAST_CONCAT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP): + VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP) + ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP): + VM_TRACE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP) + ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_USER_CALL_SPEC_CONST_TMP): + VM_TRACE(ZEND_INIT_USER_CALL_SPEC_CONST_TMP) + ZEND_INIT_USER_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INIT_USER_CALL_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP): + VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP) + ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_CONST_TMP): + VM_TRACE(ZEND_INIT_ARRAY_SPEC_CONST_TMP) + ZEND_INIT_ARRAY_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP): + VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP) + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP): + VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP) + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP): + VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP) + ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_YIELD_SPEC_CONST_TMP): + VM_TRACE(ZEND_YIELD_SPEC_CONST_TMP) + ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_YIELD_SPEC_CONST_TMP) HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_R_SPEC_CONST_UNUSED): VM_TRACE(ZEND_FETCH_R_SPEC_CONST_UNUSED) @@ -118295,10 +112491,10 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR): - VM_TRACE(ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) - ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) + HYBRID_CASE(ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP): + VM_TRACE(ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP) + ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP) HYBRID_BREAK(); HYBRID_CASE(ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED): VM_TRACE(ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) @@ -118310,36 +112506,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) HYBRID_BREAK(); - HYBRID_CASE(ZEND_BOOL_NOT_SPEC_TMPVAR): - VM_TRACE(ZEND_BOOL_NOT_SPEC_TMPVAR) - ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_BOOL_NOT_SPEC_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ECHO_SPEC_TMPVAR): - VM_TRACE(ZEND_ECHO_SPEC_TMPVAR) - ZEND_ECHO_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ECHO_SPEC_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMPZ_SPEC_TMPVAR): - VM_TRACE(ZEND_JMPZ_SPEC_TMPVAR) - ZEND_JMPZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_JMPZ_SPEC_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMPNZ_SPEC_TMPVAR): - VM_TRACE(ZEND_JMPNZ_SPEC_TMPVAR) - ZEND_JMPNZ_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_JMPNZ_SPEC_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMPZ_EX_SPEC_TMPVAR): - VM_TRACE(ZEND_JMPZ_EX_SPEC_TMPVAR) - ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_JMPZ_EX_SPEC_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMPNZ_EX_SPEC_TMPVAR): - VM_TRACE(ZEND_JMPNZ_EX_SPEC_TMPVAR) - ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_JMPNZ_EX_SPEC_TMPVAR) - HYBRID_BREAK(); HYBRID_CASE(ZEND_FREE_SPEC_TMPVAR): VM_TRACE(ZEND_FREE_SPEC_TMPVAR) ZEND_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -118350,101 +112516,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_FE_FREE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_FE_FREE_SPEC_TMPVAR) HYBRID_BREAK(); - HYBRID_CASE(ZEND_THROW_SPEC_TMPVAR): - VM_TRACE(ZEND_THROW_SPEC_TMPVAR) - ZEND_THROW_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_THROW_SPEC_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BOOL_SPEC_TMPVAR): - VM_TRACE(ZEND_BOOL_SPEC_TMPVAR) - ZEND_BOOL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_BOOL_SPEC_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CLONE_SPEC_TMPVAR): - VM_TRACE(ZEND_CLONE_SPEC_TMPVAR) - ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_CLONE_SPEC_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR): - VM_TRACE(ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR) - ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_YIELD_FROM_SPEC_TMPVAR): - VM_TRACE(ZEND_YIELD_FROM_SPEC_TMPVAR) - ZEND_YIELD_FROM_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_YIELD_FROM_SPEC_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_STRLEN_SPEC_TMPVAR): - VM_TRACE(ZEND_STRLEN_SPEC_TMPVAR) - ZEND_STRLEN_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_STRLEN_SPEC_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_TYPE_CHECK_SPEC_TMPVAR): - VM_TRACE(ZEND_TYPE_CHECK_SPEC_TMPVAR) - ZEND_TYPE_CHECK_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_TYPE_CHECK_SPEC_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR): - VM_TRACE(ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) - ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_DIV_SPEC_TMPVAR_CONST): - VM_TRACE(ZEND_DIV_SPEC_TMPVAR_CONST) - ZEND_DIV_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_DIV_SPEC_TMPVAR_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POW_SPEC_TMPVAR_CONST): - VM_TRACE(ZEND_POW_SPEC_TMPVAR_CONST) - ZEND_POW_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_POW_SPEC_TMPVAR_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CONCAT_SPEC_TMPVAR_CONST): - VM_TRACE(ZEND_CONCAT_SPEC_TMPVAR_CONST) - ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_CONCAT_SPEC_TMPVAR_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST): - VM_TRACE(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST) - ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ): - VM_TRACE(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ) - ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ): - VM_TRACE(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ) - ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST): - VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST) - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ): - VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ) - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ): - VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ) - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMPVAR_CONST): - VM_TRACE(ZEND_SPACESHIP_SPEC_TMPVAR_CONST) - ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_TMPVAR_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BOOL_XOR_SPEC_TMPVAR_CONST): - VM_TRACE(ZEND_BOOL_XOR_SPEC_TMPVAR_CONST) - ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_BOOL_XOR_SPEC_TMPVAR_CONST) - HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST): VM_TRACE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -118465,46 +112536,11 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST) HYBRID_BREAK(); - HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST): - VM_TRACE(ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST) - ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST): - VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST) - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST) - HYBRID_BREAK(); HYBRID_CASE(ZEND_SEND_VAL_SPEC_TMPVAR_CONST): VM_TRACE(ZEND_SEND_VAL_SPEC_TMPVAR_CONST) ZEND_SEND_VAL_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_SEND_VAL_SPEC_TMPVAR_CONST) HYBRID_BREAK(); - HYBRID_CASE(ZEND_CASE_SPEC_TMPVAR_CONST): - VM_TRACE(ZEND_CASE_SPEC_TMPVAR_CONST) - ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_CASE_SPEC_TMPVAR_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST): - VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST): - VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST): - VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMPVAR_CONST): - VM_TRACE(ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) - ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) - HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST): VM_TRACE(ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -118515,145 +112551,25 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) HYBRID_BREAK(); - HYBRID_CASE(ZEND_DIV_SPEC_TMPVAR_TMPVAR): - VM_TRACE(ZEND_DIV_SPEC_TMPVAR_TMPVAR) - ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_DIV_SPEC_TMPVAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POW_SPEC_TMPVAR_TMPVAR): - VM_TRACE(ZEND_POW_SPEC_TMPVAR_TMPVAR) - ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_POW_SPEC_TMPVAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CONCAT_SPEC_TMPVAR_TMPVAR): - VM_TRACE(ZEND_CONCAT_SPEC_TMPVAR_TMPVAR) - ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_CONCAT_SPEC_TMPVAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR): - VM_TRACE(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR) - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ): - VM_TRACE(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ): - VM_TRACE(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR): - VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR) - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ): - VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ): - VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR): - VM_TRACE(ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) - ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR): - VM_TRACE(ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR) - ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR): - VM_TRACE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) - ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR): - VM_TRACE(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) - ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR): - VM_TRACE(ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) - ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR): - VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CASE_SPEC_TMPVAR_TMPVAR): - VM_TRACE(ZEND_CASE_SPEC_TMPVAR_TMPVAR) - ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_CASE_SPEC_TMPVAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR): - VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR): - VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR): - VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMPVAR_VAR): - VM_TRACE(ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) - ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_R_SPEC_TMPVAR_UNUSED): - VM_TRACE(ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) - ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_W_SPEC_TMPVAR_UNUSED): - VM_TRACE(ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) - ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED): - VM_TRACE(ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) - ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED): - VM_TRACE(ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) - ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED): - VM_TRACE(ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) - ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED): - VM_TRACE(ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) - ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) + HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP): + VM_TRACE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP) + ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP): + VM_TRACE(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP) + ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP): + VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP) + ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP): + VM_TRACE(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP) + ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP) HYBRID_BREAK(); HYBRID_CASE(ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED): VM_TRACE(ZEND_SEND_VAL_SPEC_TMPVAR_UNUSED) @@ -118665,56 +112581,11 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED): - VM_TRACE(ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) - ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED): - VM_TRACE(ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) - ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_COUNT_SPEC_TMPVAR_UNUSED): - VM_TRACE(ZEND_COUNT_SPEC_TMPVAR_UNUSED) - ZEND_COUNT_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_COUNT_SPEC_TMPVAR_UNUSED) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED): - VM_TRACE(ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) - ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED): - VM_TRACE(ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) - ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) - HYBRID_BREAK(); HYBRID_CASE(ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED): VM_TRACE(ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED) ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED) HYBRID_BREAK(); - HYBRID_CASE(ZEND_DIV_SPEC_TMPVAR_CV): - VM_TRACE(ZEND_DIV_SPEC_TMPVAR_CV) - ZEND_DIV_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_DIV_SPEC_TMPVAR_CV) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POW_SPEC_TMPVAR_CV): - VM_TRACE(ZEND_POW_SPEC_TMPVAR_CV) - ZEND_POW_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_POW_SPEC_TMPVAR_CV) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CONCAT_SPEC_TMPVAR_CV): - VM_TRACE(ZEND_CONCAT_SPEC_TMPVAR_CV) - ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_CONCAT_SPEC_TMPVAR_CV) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMPVAR_CV): - VM_TRACE(ZEND_SPACESHIP_SPEC_TMPVAR_CV) - ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_TMPVAR_CV) - HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV): VM_TRACE(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -118735,35 +112606,35 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV) HYBRID_BREAK(); - HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMPVAR_CV): - VM_TRACE(ZEND_FAST_CONCAT_SPEC_TMPVAR_CV) - ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_TMPVAR_CV) + HYBRID_CASE(ZEND_BOOL_NOT_SPEC_TMP): + VM_TRACE(ZEND_BOOL_NOT_SPEC_TMP) + ZEND_BOOL_NOT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_BOOL_NOT_SPEC_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV): - VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) + HYBRID_CASE(ZEND_ECHO_SPEC_TMP): + VM_TRACE(ZEND_ECHO_SPEC_TMP) + ZEND_ECHO_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ECHO_SPEC_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_CASE_SPEC_TMPVAR_CV): - VM_TRACE(ZEND_CASE_SPEC_TMPVAR_CV) - ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_CASE_SPEC_TMPVAR_CV) + HYBRID_CASE(ZEND_JMPZ_SPEC_TMP): + VM_TRACE(ZEND_JMPZ_SPEC_TMP) + ZEND_JMPZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_JMPZ_SPEC_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV): - VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) + HYBRID_CASE(ZEND_JMPNZ_SPEC_TMP): + VM_TRACE(ZEND_JMPNZ_SPEC_TMP) + ZEND_JMPNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_JMPNZ_SPEC_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV): - VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) + HYBRID_CASE(ZEND_JMPZ_EX_SPEC_TMP): + VM_TRACE(ZEND_JMPZ_EX_SPEC_TMP) + ZEND_JMPZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_JMPZ_EX_SPEC_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV): - VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) + HYBRID_CASE(ZEND_JMPNZ_EX_SPEC_TMP): + VM_TRACE(ZEND_JMPNZ_EX_SPEC_TMP) + ZEND_JMPNZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_JMPNZ_EX_SPEC_TMP) HYBRID_BREAK(); HYBRID_CASE(ZEND_RETURN_SPEC_TMP): VM_TRACE(ZEND_RETURN_SPEC_TMP) @@ -118859,16 +112730,36 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_GENERATOR_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_GENERATOR_RETURN_SPEC_TMP) HYBRID_BREAK(); + HYBRID_CASE(ZEND_THROW_SPEC_TMP): + VM_TRACE(ZEND_THROW_SPEC_TMP) + ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_THROW_SPEC_TMP) + HYBRID_BREAK(); HYBRID_CASE(ZEND_SEND_USER_SPEC_TMP): VM_TRACE(ZEND_SEND_USER_SPEC_TMP) ZEND_SEND_USER_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_SEND_USER_SPEC_TMP) HYBRID_BREAK(); + HYBRID_CASE(ZEND_BOOL_SPEC_TMP): + VM_TRACE(ZEND_BOOL_SPEC_TMP) + ZEND_BOOL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_BOOL_SPEC_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CLONE_SPEC_TMP): + VM_TRACE(ZEND_CLONE_SPEC_TMP) + ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_CLONE_SPEC_TMP) + HYBRID_BREAK(); HYBRID_CASE(ZEND_CAST_SPEC_TMP): VM_TRACE(ZEND_CAST_SPEC_TMP) ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_CAST_SPEC_TMP) HYBRID_BREAK(); + HYBRID_CASE(ZEND_INCLUDE_OR_EVAL_SPEC_TMP): + VM_TRACE(ZEND_INCLUDE_OR_EVAL_SPEC_TMP) + ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INCLUDE_OR_EVAL_SPEC_TMP) + HYBRID_BREAK(); HYBRID_CASE(ZEND_FE_RESET_R_SPEC_TMP): VM_TRACE(ZEND_FE_RESET_R_SPEC_TMP) ZEND_FE_RESET_R_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -118879,6 +112770,11 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_FE_RESET_RW_SPEC_TMP) HYBRID_BREAK(); + HYBRID_CASE(ZEND_FE_FETCH_R_SPEC_TMP): + VM_TRACE(ZEND_FE_FETCH_R_SPEC_TMP) + ZEND_FE_FETCH_R_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FE_FETCH_R_SPEC_TMP) + HYBRID_BREAK(); HYBRID_CASE(ZEND_END_SILENCE_SPEC_TMP): VM_TRACE(ZEND_END_SILENCE_SPEC_TMP) ZEND_END_SILENCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -118904,6 +112800,41 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_QM_ASSIGN_SPEC_TMP) HYBRID_BREAK(); + HYBRID_CASE(ZEND_YIELD_FROM_SPEC_TMP): + VM_TRACE(ZEND_YIELD_FROM_SPEC_TMP) + ZEND_YIELD_FROM_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_YIELD_FROM_SPEC_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_STRLEN_SPEC_TMP): + VM_TRACE(ZEND_STRLEN_SPEC_TMP) + ZEND_STRLEN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_STRLEN_SPEC_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_TYPE_CHECK_SPEC_TMP): + VM_TRACE(ZEND_TYPE_CHECK_SPEC_TMP) + ZEND_TYPE_CHECK_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_TYPE_CHECK_SPEC_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_CLASS_NAME_SPEC_TMP): + VM_TRACE(ZEND_FETCH_CLASS_NAME_SPEC_TMP) + ZEND_FETCH_CLASS_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_CLASS_NAME_SPEC_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_DIV_SPEC_TMP_CONST): + VM_TRACE(ZEND_DIV_SPEC_TMP_CONST) + ZEND_DIV_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_DIV_SPEC_TMP_CONST) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POW_SPEC_TMP_CONST): + VM_TRACE(ZEND_POW_SPEC_TMP_CONST) + ZEND_POW_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_POW_SPEC_TMP_CONST) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CONCAT_SPEC_TMP_CONST): + VM_TRACE(ZEND_CONCAT_SPEC_TMP_CONST) + ZEND_CONCAT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_CONCAT_SPEC_TMP_CONST) + HYBRID_BREAK(); HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_TMP_CONST): VM_TRACE(ZEND_IS_IDENTICAL_SPEC_TMP_CONST) ZEND_IS_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -118919,6 +112850,46 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST) HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMP_CONST): + VM_TRACE(ZEND_IS_EQUAL_SPEC_TMP_CONST) + ZEND_IS_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMP_CONST) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ): + VM_TRACE(ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ) + ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ): + VM_TRACE(ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ) + ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST): + VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST) + ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ): + VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ) + ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ): + VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ) + ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMP_CONST): + VM_TRACE(ZEND_SPACESHIP_SPEC_TMP_CONST) + ZEND_SPACESHIP_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_TMP_CONST) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BOOL_XOR_SPEC_TMP_CONST): + VM_TRACE(ZEND_BOOL_XOR_SPEC_TMP_CONST) + ZEND_BOOL_XOR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_BOOL_XOR_SPEC_TMP_CONST) + HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST): VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST) ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -118929,6 +112900,11 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST) HYBRID_BREAK(); + HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMP_CONST): + VM_TRACE(ZEND_FAST_CONCAT_SPEC_TMP_CONST) + ZEND_FAST_CONCAT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_TMP_CONST) + HYBRID_BREAK(); HYBRID_CASE(ZEND_ROPE_ADD_SPEC_TMP_CONST): VM_TRACE(ZEND_ROPE_ADD_SPEC_TMP_CONST) ZEND_ROPE_ADD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -118939,11 +112915,21 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ROPE_END_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ROPE_END_SPEC_TMP_CONST) HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST): + VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST) + ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST) + HYBRID_BREAK(); HYBRID_CASE(ZEND_SEND_VAL_EX_SPEC_TMP_CONST): VM_TRACE(ZEND_SEND_VAL_EX_SPEC_TMP_CONST) ZEND_SEND_VAL_EX_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_SEND_VAL_EX_SPEC_TMP_CONST) HYBRID_BREAK(); + HYBRID_CASE(ZEND_CASE_SPEC_TMP_CONST): + VM_TRACE(ZEND_CASE_SPEC_TMP_CONST) + ZEND_CASE_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_CASE_SPEC_TMP_CONST) + HYBRID_BREAK(); HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST): VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST) ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -118954,6 +112940,26 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_INIT_ARRAY_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_TMP_CONST) HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST): + VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST) + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST): + VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST) + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST): + VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST) + ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMP_CONST): + VM_TRACE(ZEND_INSTANCEOF_SPEC_TMP_CONST) + ZEND_INSTANCEOF_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INSTANCEOF_SPEC_TMP_CONST) + HYBRID_BREAK(); HYBRID_CASE(ZEND_YIELD_SPEC_TMP_CONST): VM_TRACE(ZEND_YIELD_SPEC_TMP_CONST) ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -118964,40 +112970,20 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_IN_ARRAY_SPEC_TMP_CONST) HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR): - VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) - ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ROPE_ADD_SPEC_TMP_TMPVAR): - VM_TRACE(ZEND_ROPE_ADD_SPEC_TMP_TMPVAR) - ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ROPE_ADD_SPEC_TMP_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ROPE_END_SPEC_TMP_TMPVAR): - VM_TRACE(ZEND_ROPE_END_SPEC_TMP_TMPVAR) - ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ROPE_END_SPEC_TMP_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR): - VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR) - ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR): - VM_TRACE(ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR) - ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_YIELD_SPEC_TMP_TMPVAR): - VM_TRACE(ZEND_YIELD_SPEC_TMP_TMPVAR) - ZEND_YIELD_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_YIELD_SPEC_TMP_TMPVAR) + HYBRID_CASE(ZEND_DIV_SPEC_TMP_TMP): + VM_TRACE(ZEND_DIV_SPEC_TMP_TMP) + ZEND_DIV_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_DIV_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POW_SPEC_TMP_TMP): + VM_TRACE(ZEND_POW_SPEC_TMP_TMP) + ZEND_POW_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_POW_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CONCAT_SPEC_TMP_TMP): + VM_TRACE(ZEND_CONCAT_SPEC_TMP_TMP) + ZEND_CONCAT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_CONCAT_SPEC_TMP_TMP) HYBRID_BREAK(); HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_TMP_TMP): VM_TRACE(ZEND_IS_IDENTICAL_SPEC_TMP_TMP) @@ -119014,10 +113000,145 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_CASE_STRICT_SPEC_TMP_VAR): - VM_TRACE(ZEND_CASE_STRICT_SPEC_TMP_VAR) - ZEND_CASE_STRICT_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_CASE_STRICT_SPEC_TMP_VAR) + HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMP_TMP): + VM_TRACE(ZEND_IS_EQUAL_SPEC_TMP_TMP) + ZEND_IS_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ): + VM_TRACE(ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ) + ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ): + VM_TRACE(ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ) + ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP): + VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP) + ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ): + VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ) + ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ): + VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ) + ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMP_TMP): + VM_TRACE(ZEND_SPACESHIP_SPEC_TMP_TMP) + ZEND_SPACESHIP_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BOOL_XOR_SPEC_TMP_TMP): + VM_TRACE(ZEND_BOOL_XOR_SPEC_TMP_TMP) + ZEND_BOOL_XOR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_BOOL_XOR_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP): + VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP) + ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP): + VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP) + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMP_TMP): + VM_TRACE(ZEND_FAST_CONCAT_SPEC_TMP_TMP) + ZEND_FAST_CONCAT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ROPE_ADD_SPEC_TMP_TMP): + VM_TRACE(ZEND_ROPE_ADD_SPEC_TMP_TMP) + ZEND_ROPE_ADD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ROPE_ADD_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ROPE_END_SPEC_TMP_TMP): + VM_TRACE(ZEND_ROPE_END_SPEC_TMP_TMP) + ZEND_ROPE_END_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ROPE_END_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP): + VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP) + ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CASE_SPEC_TMP_TMP): + VM_TRACE(ZEND_CASE_SPEC_TMP_TMP) + ZEND_CASE_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_CASE_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP): + VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP) + ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_TMP_TMP): + VM_TRACE(ZEND_INIT_ARRAY_SPEC_TMP_TMP) + ZEND_INIT_ARRAY_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP): + VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP) + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP): + VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP) + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP): + VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP) + ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_YIELD_SPEC_TMP_TMP): + VM_TRACE(ZEND_YIELD_SPEC_TMP_TMP) + ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_YIELD_SPEC_TMP_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMP_VAR): + VM_TRACE(ZEND_INSTANCEOF_SPEC_TMP_VAR) + ZEND_INSTANCEOF_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INSTANCEOF_SPEC_TMP_VAR) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_R_SPEC_TMP_UNUSED): + VM_TRACE(ZEND_FETCH_R_SPEC_TMP_UNUSED) + ZEND_FETCH_R_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_R_SPEC_TMP_UNUSED) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_W_SPEC_TMP_UNUSED): + VM_TRACE(ZEND_FETCH_W_SPEC_TMP_UNUSED) + ZEND_FETCH_W_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_W_SPEC_TMP_UNUSED) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_RW_SPEC_TMP_UNUSED): + VM_TRACE(ZEND_FETCH_RW_SPEC_TMP_UNUSED) + ZEND_FETCH_RW_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_RW_SPEC_TMP_UNUSED) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED): + VM_TRACE(ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED) + ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_UNSET_SPEC_TMP_UNUSED): + VM_TRACE(ZEND_FETCH_UNSET_SPEC_TMP_UNUSED) + ZEND_FETCH_UNSET_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_UNSET_SPEC_TMP_UNUSED) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_IS_SPEC_TMP_UNUSED): + VM_TRACE(ZEND_FETCH_IS_SPEC_TMP_UNUSED) + ZEND_FETCH_IS_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_IS_SPEC_TMP_UNUSED) HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED): VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED) @@ -119049,21 +113170,66 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_TMP_UNUSED) HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED): + VM_TRACE(ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED) + ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INSTANCEOF_SPEC_TMP_UNUSED): + VM_TRACE(ZEND_INSTANCEOF_SPEC_TMP_UNUSED) + ZEND_INSTANCEOF_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INSTANCEOF_SPEC_TMP_UNUSED) + HYBRID_BREAK(); HYBRID_CASE(ZEND_YIELD_SPEC_TMP_UNUSED): VM_TRACE(ZEND_YIELD_SPEC_TMP_UNUSED) ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_YIELD_SPEC_TMP_UNUSED) HYBRID_BREAK(); + HYBRID_CASE(ZEND_COUNT_SPEC_TMP_UNUSED): + VM_TRACE(ZEND_COUNT_SPEC_TMP_UNUSED) + ZEND_COUNT_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_COUNT_SPEC_TMP_UNUSED) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED): + VM_TRACE(ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED) + ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_GET_CLASS_SPEC_TMP_UNUSED): + VM_TRACE(ZEND_GET_CLASS_SPEC_TMP_UNUSED) + ZEND_GET_CLASS_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_GET_CLASS_SPEC_TMP_UNUSED) + HYBRID_BREAK(); HYBRID_CASE(ZEND_GET_TYPE_SPEC_TMP_UNUSED): VM_TRACE(ZEND_GET_TYPE_SPEC_TMP_UNUSED) ZEND_GET_TYPE_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_GET_TYPE_SPEC_TMP_UNUSED) HYBRID_BREAK(); + HYBRID_CASE(ZEND_DIV_SPEC_TMP_CV): + VM_TRACE(ZEND_DIV_SPEC_TMP_CV) + ZEND_DIV_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_DIV_SPEC_TMP_CV) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POW_SPEC_TMP_CV): + VM_TRACE(ZEND_POW_SPEC_TMP_CV) + ZEND_POW_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_POW_SPEC_TMP_CV) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CONCAT_SPEC_TMP_CV): + VM_TRACE(ZEND_CONCAT_SPEC_TMP_CV) + ZEND_CONCAT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_CONCAT_SPEC_TMP_CV) + HYBRID_BREAK(); HYBRID_CASE(ZEND_CASE_STRICT_SPEC_TMP_CV): VM_TRACE(ZEND_CASE_STRICT_SPEC_TMP_CV) ZEND_CASE_STRICT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_CASE_STRICT_SPEC_TMP_CV) HYBRID_BREAK(); + HYBRID_CASE(ZEND_SPACESHIP_SPEC_TMP_CV): + VM_TRACE(ZEND_SPACESHIP_SPEC_TMP_CV) + ZEND_SPACESHIP_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_TMP_CV) + HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV): VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV) ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -119074,6 +113240,11 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV) HYBRID_BREAK(); + HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_TMP_CV): + VM_TRACE(ZEND_FAST_CONCAT_SPEC_TMP_CV) + ZEND_FAST_CONCAT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_TMP_CV) + HYBRID_BREAK(); HYBRID_CASE(ZEND_ROPE_ADD_SPEC_TMP_CV): VM_TRACE(ZEND_ROPE_ADD_SPEC_TMP_CV) ZEND_ROPE_ADD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -119084,6 +113255,16 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ROPE_END_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ROPE_END_SPEC_TMP_CV) HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_TMP_CV): + VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_TMP_CV) + ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_TMP_CV) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CASE_SPEC_TMP_CV): + VM_TRACE(ZEND_CASE_SPEC_TMP_CV) + ZEND_CASE_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_CASE_SPEC_TMP_CV) + HYBRID_BREAK(); HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV): VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV) ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -119094,6 +113275,21 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_TMP_CV) HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV): + VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV) + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV): + VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV) + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV): + VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV) + ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV) + HYBRID_BREAK(); HYBRID_CASE(ZEND_YIELD_SPEC_TMP_CV): VM_TRACE(ZEND_YIELD_SPEC_TMP_CV) ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -119134,90 +113330,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_POST_DEC_SPEC_VAR) HYBRID_BREAK(); - HYBRID_CASE(ZEND_RETURN_SPEC_VAR): - VM_TRACE(ZEND_RETURN_SPEC_VAR) -{ - USE_OPLINE - zval *retval_ptr; - zval *return_value; - - - retval_ptr = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - return_value = EX(return_value); - - - if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(retval_ptr) == IS_UNDEF)) { - SAVE_OPLINE(); - retval_ptr = ZVAL_UNDEFINED_OP1(); - if (return_value) { - ZVAL_NULL(return_value); - } - } else if (!return_value) { - if (IS_VAR & (IS_VAR|IS_TMP_VAR)) { - if (Z_REFCOUNTED_P(retval_ptr) && !Z_DELREF_P(retval_ptr)) { - SAVE_OPLINE(); - rc_dtor_func(Z_COUNTED_P(retval_ptr)); - } - } - } else { - if ((IS_VAR & (IS_CONST|IS_TMP_VAR))) { - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (IS_VAR == IS_CONST) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(return_value))) { - Z_ADDREF_P(return_value); - } - } - } else if (IS_VAR == IS_CV) { - do { - if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - if (EXPECTED(!Z_OPT_ISREF_P(retval_ptr))) { - if (EXPECTED(!(EX_CALL_INFO() & (ZEND_CALL_CODE|ZEND_CALL_OBSERVED)))) { - zend_refcounted *ref = Z_COUNTED_P(retval_ptr); - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (GC_MAY_LEAK(ref)) { - SAVE_OPLINE(); - gc_possible_root(ref); - } - ZVAL_NULL(retval_ptr); - break; - } else { - Z_ADDREF_P(retval_ptr); - } - } else { - retval_ptr = Z_REFVAL_P(retval_ptr); - if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } - } - } - ZVAL_COPY_VALUE(return_value, retval_ptr); - } while (0); - } else /* if (IS_VAR == IS_VAR) */ { - if (UNEXPECTED(Z_ISREF_P(retval_ptr))) { - zend_refcounted *ref = Z_COUNTED_P(retval_ptr); - - retval_ptr = Z_REFVAL_P(retval_ptr); - ZVAL_COPY_VALUE(return_value, retval_ptr); - if (UNEXPECTED(GC_DELREF(ref) == 0)) { - efree_size(ref, sizeof(zend_reference)); - } else if (Z_OPT_REFCOUNTED_P(retval_ptr)) { - Z_ADDREF_P(retval_ptr); - } - } else { - ZVAL_COPY_VALUE(return_value, retval_ptr); - } - } - } - - - - - - - goto zend_leave_helper_SPEC_LABEL; -} - - VM_TRACE_OP_END(ZEND_RETURN_SPEC_VAR) HYBRID_CASE(ZEND_RETURN_BY_REF_SPEC_VAR): VM_TRACE(ZEND_RETURN_BY_REF_SPEC_VAR) ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -119228,51 +113340,16 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_GENERATOR_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_GENERATOR_RETURN_SPEC_VAR) HYBRID_BREAK(); - HYBRID_CASE(ZEND_SEND_USER_SPEC_VAR): - VM_TRACE(ZEND_SEND_USER_SPEC_VAR) - ZEND_SEND_USER_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_SEND_USER_SPEC_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CAST_SPEC_VAR): - VM_TRACE(ZEND_CAST_SPEC_VAR) - ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_CAST_SPEC_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FE_RESET_R_SPEC_VAR): - VM_TRACE(ZEND_FE_RESET_R_SPEC_VAR) - ZEND_FE_RESET_R_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FE_RESET_R_SPEC_VAR) - HYBRID_BREAK(); HYBRID_CASE(ZEND_FE_RESET_RW_SPEC_VAR): VM_TRACE(ZEND_FE_RESET_RW_SPEC_VAR) ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_FE_RESET_RW_SPEC_VAR) HYBRID_BREAK(); - HYBRID_CASE(ZEND_FE_FETCH_R_SPEC_VAR): - VM_TRACE(ZEND_FE_FETCH_R_SPEC_VAR) - ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FE_FETCH_R_SPEC_VAR) - HYBRID_BREAK(); HYBRID_CASE(ZEND_FE_FETCH_RW_SPEC_VAR): VM_TRACE(ZEND_FE_FETCH_RW_SPEC_VAR) ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_FE_FETCH_RW_SPEC_VAR) HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMP_SET_SPEC_VAR): - VM_TRACE(ZEND_JMP_SET_SPEC_VAR) - ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_JMP_SET_SPEC_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_COALESCE_SPEC_VAR): - VM_TRACE(ZEND_COALESCE_SPEC_VAR) - ZEND_COALESCE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_COALESCE_SPEC_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_JMP_NULL_SPEC_VAR): - VM_TRACE(ZEND_JMP_NULL_SPEC_VAR) - ZEND_JMP_NULL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_JMP_NULL_SPEC_VAR) - HYBRID_BREAK(); HYBRID_CASE(ZEND_QM_ASSIGN_SPEC_VAR): VM_TRACE(ZEND_QM_ASSIGN_SPEC_VAR) ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -119283,21 +113360,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_SEND_VAR_SIMPLE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_SEND_VAR_SIMPLE_SPEC_VAR) HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_VAR_CONST): - VM_TRACE(ZEND_IS_IDENTICAL_SPEC_VAR_CONST) - ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_IDENTICAL_SPEC_VAR_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CASE_STRICT_SPEC_VAR_CONST): - VM_TRACE(ZEND_CASE_STRICT_SPEC_VAR_CONST) - ZEND_CASE_STRICT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_CASE_STRICT_SPEC_VAR_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST): - VM_TRACE(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST) - ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST) - HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST): VM_TRACE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST) ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -119378,11 +113440,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR) - ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR) - HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV): VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV) ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -119398,11 +113455,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR) - ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR) - HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV): VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV) ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -119493,180 +113545,110 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_YIELD_SPEC_VAR_CONST) HYBRID_BREAK(); - HYBRID_CASE(ZEND_IN_ARRAY_SPEC_VAR_CONST): - VM_TRACE(ZEND_IN_ARRAY_SPEC_VAR_CONST) - ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IN_ARRAY_SPEC_VAR_CONST) - HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV): VM_TRACE(ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_TMPVARCV) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR) - ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR) - ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR) - ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) - ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) - ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) - ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) - ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) - ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) - ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) - ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) - ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) - ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) - ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST) - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP) - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR) - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV) - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST): - VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST) - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP): - VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP) - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR) - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV): - VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV) - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR) - ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV): - VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV) - ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) - ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR) - ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR) - ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_UNSET_DIM_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_UNSET_DIM_SPEC_VAR_TMPVAR) - ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_UNSET_DIM_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR) - ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_YIELD_SPEC_VAR_TMPVAR): - VM_TRACE(ZEND_YIELD_SPEC_VAR_TMPVAR) - ZEND_YIELD_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_YIELD_SPEC_VAR_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_VAR_TMP): - VM_TRACE(ZEND_IS_IDENTICAL_SPEC_VAR_TMP) - ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_IDENTICAL_SPEC_VAR_TMP) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CASE_STRICT_SPEC_VAR_TMP): - VM_TRACE(ZEND_CASE_STRICT_SPEC_VAR_TMP) - ZEND_CASE_STRICT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_CASE_STRICT_SPEC_VAR_TMP) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP): - VM_TRACE(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP) - ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP) + HYBRID_CASE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP): + VM_TRACE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP) + ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP): + VM_TRACE(ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP) + ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OP_SPEC_VAR_TMP): + VM_TRACE(ZEND_ASSIGN_OP_SPEC_VAR_TMP) + ZEND_ASSIGN_OP_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OP_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_VAR_TMP): + VM_TRACE(ZEND_PRE_INC_OBJ_SPEC_VAR_TMP) + ZEND_PRE_INC_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_PRE_INC_OBJ_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_VAR_TMP): + VM_TRACE(ZEND_POST_INC_OBJ_SPEC_VAR_TMP) + ZEND_POST_INC_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_POST_INC_OBJ_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_W_SPEC_VAR_TMP): + VM_TRACE(ZEND_FETCH_DIM_W_SPEC_VAR_TMP) + ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_W_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_RW_SPEC_VAR_TMP): + VM_TRACE(ZEND_FETCH_DIM_RW_SPEC_VAR_TMP) + ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_RW_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP): + VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP) + ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP): + VM_TRACE(ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP) + ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_VAR_TMP): + VM_TRACE(ZEND_FETCH_OBJ_W_SPEC_VAR_TMP) + ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_W_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP): + VM_TRACE(ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP) + ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP): + VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP) + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP): + VM_TRACE(ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP) + ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_LIST_W_SPEC_VAR_TMP): + VM_TRACE(ZEND_FETCH_LIST_W_SPEC_VAR_TMP) + ZEND_FETCH_LIST_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_LIST_W_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST): + VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST) + ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP): + VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP) + ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV): + VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV) + ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST): + VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST) + ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP): + VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP) + ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV): + VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV) + ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV) HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED): VM_TRACE(ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED) @@ -119678,30 +113660,45 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED) HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_VAR_VAR): - VM_TRACE(ZEND_IS_IDENTICAL_SPEC_VAR_VAR) - ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_IDENTICAL_SPEC_VAR_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CASE_STRICT_SPEC_VAR_VAR): - VM_TRACE(ZEND_CASE_STRICT_SPEC_VAR_VAR) - ZEND_CASE_STRICT_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_CASE_STRICT_SPEC_VAR_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR): - VM_TRACE(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR) - ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED): - VM_TRACE(ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED) - ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED): - VM_TRACE(ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED) - ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED) + HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR): + VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR) + ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV): + VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV) + ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP): + VM_TRACE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP) + ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP): + VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP) + ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_VAR_TMP): + VM_TRACE(ZEND_INIT_ARRAY_SPEC_VAR_TMP) + ZEND_INIT_ARRAY_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_UNSET_DIM_SPEC_VAR_TMP): + VM_TRACE(ZEND_UNSET_DIM_SPEC_VAR_TMP) + ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_UNSET_DIM_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_VAR_TMP): + VM_TRACE(ZEND_UNSET_OBJ_SPEC_VAR_TMP) + ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_UNSET_OBJ_SPEC_VAR_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_YIELD_SPEC_VAR_TMP): + VM_TRACE(ZEND_YIELD_SPEC_VAR_TMP) + ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_YIELD_SPEC_VAR_TMP) HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_REF_SPEC_VAR_VAR): VM_TRACE(ZEND_ASSIGN_REF_SPEC_VAR_VAR) @@ -119738,11 +113735,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR) - ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR) - HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV): VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV) ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -119828,21 +113820,16 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_MAKE_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_MAKE_REF_SPEC_VAR_UNUSED) HYBRID_BREAK(); - HYBRID_CASE(ZEND_GET_TYPE_SPEC_VAR_UNUSED): - VM_TRACE(ZEND_GET_TYPE_SPEC_VAR_UNUSED) - ZEND_GET_TYPE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_GET_TYPE_SPEC_VAR_UNUSED) + HYBRID_CASE(ZEND_DEREF_SPEC_VAR_UNUSED): + VM_TRACE(ZEND_DEREF_SPEC_VAR_UNUSED) + ZEND_DEREF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_DEREF_SPEC_VAR_UNUSED) HYBRID_BREAK(); HYBRID_CASE(ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED): VM_TRACE(ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) HYBRID_BREAK(); - HYBRID_CASE(ZEND_CASE_STRICT_SPEC_VAR_CV): - VM_TRACE(ZEND_CASE_STRICT_SPEC_VAR_CV) - ZEND_CASE_STRICT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_CASE_STRICT_SPEC_VAR_CV) - HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV): VM_TRACE(ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV) ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -119923,11 +113910,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR) - ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR) - HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV): VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV) ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -119943,11 +113925,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR) - ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR) - HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV): VM_TRACE(ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV) ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -120083,11 +114060,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR) - ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR) - HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV): VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV) ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -120163,120 +114135,115 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_TMPVARCV) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR): - VM_TRACE(ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR) - ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR): - VM_TRACE(ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) - ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR): - VM_TRACE(ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) - ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) - ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) - ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) - ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) - ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) - ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST) - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP) - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR) - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV) - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR) - ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV): - VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV) - ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR): - VM_TRACE(ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR) - ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR): - VM_TRACE(ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) - ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR): - VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) - ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR): - VM_TRACE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) - ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR): - VM_TRACE(ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR) - ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR): - VM_TRACE(ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR) - ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR): - VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_YIELD_SPEC_UNUSED_TMPVAR): - VM_TRACE(ZEND_YIELD_SPEC_UNUSED_TMPVAR) - ZEND_YIELD_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_YIELD_SPEC_UNUSED_TMPVAR) + HYBRID_CASE(ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP): + VM_TRACE(ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP) + ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP): + VM_TRACE(ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP) + ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP): + VM_TRACE(ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP) + ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP): + VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP) + ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP): + VM_TRACE(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP) + ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP): + VM_TRACE(ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP) + ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP): + VM_TRACE(ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP) + ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP): + VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP) + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP): + VM_TRACE(ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP) + ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST): + VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST) + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP): + VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP) + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV): + VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV) + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR): + VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR) + ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV): + VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV) + ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ROPE_INIT_SPEC_UNUSED_TMP): + VM_TRACE(ZEND_ROPE_INIT_SPEC_UNUSED_TMP) + ZEND_ROPE_INIT_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ROPE_INIT_SPEC_UNUSED_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_CLASS_SPEC_UNUSED_TMP): + VM_TRACE(ZEND_FETCH_CLASS_SPEC_UNUSED_TMP) + ZEND_FETCH_CLASS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_CLASS_SPEC_UNUSED_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP): + VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP) + ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP): + VM_TRACE(ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP) + ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_UNUSED_TMP): + VM_TRACE(ZEND_INIT_ARRAY_SPEC_UNUSED_TMP) + ZEND_INIT_ARRAY_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_UNUSED_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_UNUSED_TMP): + VM_TRACE(ZEND_UNSET_OBJ_SPEC_UNUSED_TMP) + ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_UNSET_OBJ_SPEC_UNUSED_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP): + VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP) + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_YIELD_SPEC_UNUSED_TMP): + VM_TRACE(ZEND_YIELD_SPEC_UNUSED_TMP) + ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_YIELD_SPEC_UNUSED_TMP) HYBRID_BREAK(); HYBRID_CASE(ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED): VM_TRACE(ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED) @@ -120433,11 +114400,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR) - ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR) - HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV): VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV) ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -120962,11 +114924,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR) - ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR) - HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV): VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV) ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -120982,11 +114939,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR) - ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR) - HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV): VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV) ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -121112,245 +115064,20 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) HYBRID_BREAK(); - HYBRID_CASE(ZEND_DIV_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_DIV_SPEC_CV_TMPVAR) - ZEND_DIV_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_DIV_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POW_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_POW_SPEC_CV_TMPVAR) - ZEND_POW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_POW_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_CONCAT_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_CONCAT_SPEC_CV_TMPVAR) - ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_CONCAT_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_IS_EQUAL_SPEC_CV_TMPVAR) - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ): - VM_TRACE(ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ) - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ): - VM_TRACE(ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ) - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR) - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ): - VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ) - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ): - VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ) - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_SPACESHIP_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_SPACESHIP_SPEC_CV_TMPVAR) - ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_BOOL_XOR_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_BOOL_XOR_SPEC_CV_TMPVAR) - ZEND_BOOL_XOR_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_BOOL_XOR_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR) - ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR) - ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OP_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_ASSIGN_OP_SPEC_CV_TMPVAR) - ZEND_ASSIGN_OP_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OP_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) - ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) - ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) - ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) - ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) - ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) - ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) - ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) - ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) - ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) - ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) - ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) - ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST) - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP) - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR) - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV) - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST): - VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST) - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP): - VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP) - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR) - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV): - VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV) - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR) - ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV): - VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV) - ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_FAST_CONCAT_SPEC_CV_TMPVAR) - ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) - ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR) - ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_INIT_ARRAY_SPEC_CV_TMPVAR) - ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_UNSET_DIM_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_UNSET_DIM_SPEC_CV_TMPVAR) - ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_UNSET_DIM_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_UNSET_OBJ_SPEC_CV_TMPVAR) - ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_UNSET_OBJ_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) - ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_YIELD_SPEC_CV_TMPVAR): - VM_TRACE(ZEND_YIELD_SPEC_CV_TMPVAR) - ZEND_YIELD_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_YIELD_SPEC_CV_TMPVAR) + HYBRID_CASE(ZEND_DIV_SPEC_CV_TMP): + VM_TRACE(ZEND_DIV_SPEC_CV_TMP) + ZEND_DIV_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_DIV_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POW_SPEC_CV_TMP): + VM_TRACE(ZEND_POW_SPEC_CV_TMP) + ZEND_POW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_POW_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_CONCAT_SPEC_CV_TMP): + VM_TRACE(ZEND_CONCAT_SPEC_CV_TMP) + ZEND_CONCAT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_CONCAT_SPEC_CV_TMP) HYBRID_BREAK(); HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_CV_TMP): VM_TRACE(ZEND_IS_IDENTICAL_SPEC_CV_TMP) @@ -121362,6 +115089,161 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP) HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_EQUAL_SPEC_CV_TMP): + VM_TRACE(ZEND_IS_EQUAL_SPEC_CV_TMP) + ZEND_IS_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ): + VM_TRACE(ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ) + ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ): + VM_TRACE(ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ) + ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP): + VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP) + ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ): + VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ) + ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ): + VM_TRACE(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ) + ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_SPACESHIP_SPEC_CV_TMP): + VM_TRACE(ZEND_SPACESHIP_SPEC_CV_TMP) + ZEND_SPACESHIP_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_SPACESHIP_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_BOOL_XOR_SPEC_CV_TMP): + VM_TRACE(ZEND_BOOL_XOR_SPEC_CV_TMP) + ZEND_BOOL_XOR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_BOOL_XOR_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP): + VM_TRACE(ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP) + ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP): + VM_TRACE(ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP) + ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OP_SPEC_CV_TMP): + VM_TRACE(ZEND_ASSIGN_OP_SPEC_CV_TMP) + ZEND_ASSIGN_OP_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OP_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_PRE_INC_OBJ_SPEC_CV_TMP): + VM_TRACE(ZEND_PRE_INC_OBJ_SPEC_CV_TMP) + ZEND_PRE_INC_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_PRE_INC_OBJ_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_POST_INC_OBJ_SPEC_CV_TMP): + VM_TRACE(ZEND_POST_INC_OBJ_SPEC_CV_TMP) + ZEND_POST_INC_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_POST_INC_OBJ_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_R_SPEC_CV_TMP): + VM_TRACE(ZEND_FETCH_DIM_R_SPEC_CV_TMP) + ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_R_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_W_SPEC_CV_TMP): + VM_TRACE(ZEND_FETCH_DIM_W_SPEC_CV_TMP) + ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_W_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_RW_SPEC_CV_TMP): + VM_TRACE(ZEND_FETCH_DIM_RW_SPEC_CV_TMP) + ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_RW_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_IS_SPEC_CV_TMP): + VM_TRACE(ZEND_FETCH_DIM_IS_SPEC_CV_TMP) + ZEND_FETCH_DIM_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_IS_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP): + VM_TRACE(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP) + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP): + VM_TRACE(ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP) + ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_R_SPEC_CV_TMP): + VM_TRACE(ZEND_FETCH_OBJ_R_SPEC_CV_TMP) + ZEND_FETCH_OBJ_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_R_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_W_SPEC_CV_TMP): + VM_TRACE(ZEND_FETCH_OBJ_W_SPEC_CV_TMP) + ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_W_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_RW_SPEC_CV_TMP): + VM_TRACE(ZEND_FETCH_OBJ_RW_SPEC_CV_TMP) + ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_RW_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_IS_SPEC_CV_TMP): + VM_TRACE(ZEND_FETCH_OBJ_IS_SPEC_CV_TMP) + ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_IS_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP): + VM_TRACE(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP) + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP): + VM_TRACE(ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP) + ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST): + VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST) + ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP): + VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP) + ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV): + VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV) + ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST): + VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST) + ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP): + VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP) + ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV): + VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV) + ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV) + HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED): VM_TRACE(ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED) ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -121372,25 +115254,65 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED) HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_IDENTICAL_SPEC_CV_VAR): - VM_TRACE(ZEND_IS_IDENTICAL_SPEC_CV_VAR) - ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_IDENTICAL_SPEC_CV_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR): - VM_TRACE(ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR) - ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED): - VM_TRACE(ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED) - ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED) - HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED): - VM_TRACE(ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED) - ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED) + HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR): + VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR) + ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV): + VM_TRACE(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV) + ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_FAST_CONCAT_SPEC_CV_TMP): + VM_TRACE(ZEND_FAST_CONCAT_SPEC_CV_TMP) + ZEND_FAST_CONCAT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_FAST_CONCAT_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_METHOD_CALL_SPEC_CV_TMP): + VM_TRACE(ZEND_INIT_METHOD_CALL_SPEC_CV_TMP) + ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INIT_METHOD_CALL_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP): + VM_TRACE(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP) + ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_INIT_ARRAY_SPEC_CV_TMP): + VM_TRACE(ZEND_INIT_ARRAY_SPEC_CV_TMP) + ZEND_INIT_ARRAY_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_INIT_ARRAY_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_UNSET_DIM_SPEC_CV_TMP): + VM_TRACE(ZEND_UNSET_DIM_SPEC_CV_TMP) + ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_UNSET_DIM_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_UNSET_OBJ_SPEC_CV_TMP): + VM_TRACE(ZEND_UNSET_OBJ_SPEC_CV_TMP) + ZEND_UNSET_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_UNSET_OBJ_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP): + VM_TRACE(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP) + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP): + VM_TRACE(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP) + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP): + VM_TRACE(ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP) + ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP) + HYBRID_BREAK(); + HYBRID_CASE(ZEND_YIELD_SPEC_CV_TMP): + VM_TRACE(ZEND_YIELD_SPEC_CV_TMP) + ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + VM_TRACE_OP_END(ZEND_YIELD_SPEC_CV_TMP) HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_REF_SPEC_CV_VAR): VM_TRACE(ZEND_ASSIGN_REF_SPEC_CV_VAR) @@ -121462,11 +115384,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR) - ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR) - HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV): VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV) ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -121737,11 +115654,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR) - ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR) - HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV): VM_TRACE(ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV) ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -121757,11 +115669,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP) HYBRID_BREAK(); - HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR): - VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR) - ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR) - HYBRID_BREAK(); HYBRID_CASE(ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV): VM_TRACE(ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV) ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -122007,28 +115914,28 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_DIV_SPEC_CONST_CONST_HANDLER, - ZEND_DIV_SPEC_CONST_TMPVAR_HANDLER, - ZEND_DIV_SPEC_CONST_TMPVAR_HANDLER, + ZEND_DIV_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_DIV_SPEC_CONST_CV_HANDLER, - ZEND_DIV_SPEC_TMPVAR_CONST_HANDLER, - ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_DIV_SPEC_TMP_CONST_HANDLER, + ZEND_DIV_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_DIV_SPEC_TMP_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_DIV_SPEC_TMPVAR_CV_HANDLER, - ZEND_DIV_SPEC_TMPVAR_CONST_HANDLER, - ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_DIV_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_DIV_SPEC_TMPVAR_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_DIV_SPEC_CV_CONST_HANDLER, - ZEND_DIV_SPEC_CV_TMPVAR_HANDLER, - ZEND_DIV_SPEC_CV_TMPVAR_HANDLER, + ZEND_DIV_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_DIV_SPEC_CV_CV_HANDLER, ZEND_MOD_SPEC_CONST_CONST_HANDLER, @@ -122107,28 +116014,28 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_SR_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_NULL_HANDLER, - ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER, - ZEND_CONCAT_SPEC_CONST_TMPVAR_HANDLER, + ZEND_CONCAT_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_CONCAT_SPEC_CONST_CV_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_CONCAT_SPEC_TMP_CONST_HANDLER, + ZEND_CONCAT_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_CONCAT_SPEC_TMP_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_CONST_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_CONCAT_SPEC_CV_CONST_HANDLER, - ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER, - ZEND_CONCAT_SPEC_CV_TMPVAR_HANDLER, + ZEND_CONCAT_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_CONCAT_SPEC_CV_CV_HANDLER, ZEND_BW_OR_SPEC_CONST_CONST_HANDLER, @@ -122207,28 +116114,28 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_HANDLER, ZEND_POW_SPEC_CONST_CONST_HANDLER, - ZEND_POW_SPEC_CONST_TMPVAR_HANDLER, - ZEND_POW_SPEC_CONST_TMPVAR_HANDLER, + ZEND_POW_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_POW_SPEC_CONST_CV_HANDLER, - ZEND_POW_SPEC_TMPVAR_CONST_HANDLER, - ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_POW_SPEC_TMP_CONST_HANDLER, + ZEND_POW_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_POW_SPEC_TMP_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_POW_SPEC_TMPVAR_CV_HANDLER, - ZEND_POW_SPEC_TMPVAR_CONST_HANDLER, - ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_POW_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_POW_SPEC_TMPVAR_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_POW_SPEC_CV_CONST_HANDLER, - ZEND_POW_SPEC_CV_TMPVAR_HANDLER, - ZEND_POW_SPEC_CV_TMPVAR_HANDLER, + ZEND_POW_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_POW_SPEC_CV_CV_HANDLER, ZEND_BW_NOT_SPEC_CONST_HANDLER, @@ -122237,8 +116144,8 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_BW_NOT_SPEC_TMPVARCV_HANDLER, ZEND_BOOL_NOT_SPEC_CONST_HANDLER, - ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_NOT_SPEC_TMPVAR_HANDLER, + ZEND_BOOL_NOT_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_BOOL_NOT_SPEC_CV_HANDLER, ZEND_BOOL_XOR_SPEC_CONST_CONST_HANDLER, @@ -122246,14 +116153,14 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HANDLER, - ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_BOOL_XOR_SPEC_TMP_CONST_HANDLER, + ZEND_BOOL_XOR_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_HANDLER, - ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -122262,8 +116169,8 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_BOOL_XOR_SPEC_CV_CONST_HANDLER, - ZEND_BOOL_XOR_SPEC_CV_TMPVAR_HANDLER, - ZEND_BOOL_XOR_SPEC_CV_TMPVAR_HANDLER, + ZEND_BOOL_XOR_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_BOOL_XOR_SPEC_CV_CV_HANDLER, ZEND_IS_IDENTICAL_SPEC_CONST_CONST_HANDLER, @@ -122276,9 +116183,9 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER, - ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER, - ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -122288,7 +116195,7 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_IS_IDENTICAL_SPEC_CV_CONST_HANDLER, ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER, - ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_IS_IDENTICAL_SPEC_CV_CV_HANDLER, ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST_HANDLER, @@ -122301,9 +116208,9 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_HANDLER, - ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_HANDLER, - ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -122313,7 +116220,7 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_HANDLER, ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER, - ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_HANDLER, ZEND_IS_EQUAL_SPEC_CONST_CONST_HANDLER, @@ -122331,30 +116238,30 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER, + ZEND_IS_EQUAL_SPEC_TMP_CONST_HANDLER, + ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ_HANDLER, + ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ_HANDLER, + ZEND_IS_EQUAL_SPEC_TMP_TMP_HANDLER, + ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ_HANDLER, + ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -122379,12 +116286,12 @@ void zend_vm_init(void) ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER, ZEND_IS_EQUAL_SPEC_CV_CONST_JMPZ_HANDLER, ZEND_IS_EQUAL_SPEC_CV_CONST_JMPNZ_HANDLER, - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLER, - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ_HANDLER, - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ_HANDLER, - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLER, - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ_HANDLER, - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ_HANDLER, + ZEND_IS_EQUAL_SPEC_CV_TMP_HANDLER, + ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ_HANDLER, + ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -122406,30 +116313,30 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -122454,12 +116361,12 @@ void zend_vm_init(void) ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HANDLER, ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPZ_HANDLER, ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPNZ_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -122640,8 +116547,8 @@ void zend_vm_init(void) ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_USED_HANDLER, ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED_HANDLER, ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED_HANDLER, - ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED_HANDLER, - ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_UNUSED_HANDLER, @@ -122660,8 +116567,8 @@ void zend_vm_init(void) ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_USED_HANDLER, ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_HANDLER, ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_HANDLER, - ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED_HANDLER, - ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSED_HANDLER, @@ -122718,27 +116625,27 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CONST_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CONST_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV_HANDLER, ZEND_NULL_HANDLER, @@ -122768,27 +116675,27 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_HANDLER, ZEND_NULL_HANDLER, @@ -122843,19 +116750,19 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER, ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -122863,24 +116770,24 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_HANDLER, ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_HANDLER, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_HANDLER, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -122888,24 +116795,24 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST_HANDLER, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER, ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST_HANDLER, ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -122913,12 +116820,12 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_HANDLER, ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_HANDLER, ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CONST_HANDLER, ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_TMP_HANDLER, - ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV_HANDLER, ZEND_NULL_HANDLER, @@ -122932,8 +116839,8 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_OP_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_OP_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_OP_SPEC_VAR_CV_HANDLER, ZEND_NULL_HANDLER, @@ -122942,8 +116849,8 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_OP_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_OP_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_OP_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_OP_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_OP_SPEC_CV_CV_HANDLER, ZEND_NULL_HANDLER, @@ -122957,8 +116864,8 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_HANDLER, ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_HANDLER, ZEND_NULL_HANDLER, @@ -122967,8 +116874,8 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_HANDLER, ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_HANDLER, ZEND_NULL_HANDLER, @@ -122982,18 +116889,18 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST_HANDLER, - ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_HANDLER, ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CONST_HANDLER, - ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CV_HANDLER, ZEND_ASSIGN_OBJ_OP_SPEC_CV_CONST_HANDLER, - ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_HANDLER, - ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_HANDLER, + ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV_HANDLER, ZEND_ASSIGN_STATIC_PROP_OP_SPEC_HANDLER, @@ -123084,14 +116991,14 @@ void zend_vm_init(void) ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -123109,14 +117016,14 @@ void zend_vm_init(void) ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -123134,14 +117041,14 @@ void zend_vm_init(void) ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER, + ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -123187,30 +117094,30 @@ void zend_vm_init(void) ZEND_POST_INC_STATIC_PROP_SPEC_HANDLER, ZEND_JMP_SPEC_HANDLER, ZEND_JMPZ_SPEC_CONST_HANDLER, - ZEND_JMPZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_SPEC_TMPVAR_HANDLER, + ZEND_JMPZ_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_JMPZ_SPEC_CV_HANDLER, ZEND_JMPNZ_SPEC_CONST_HANDLER, - ZEND_JMPNZ_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_SPEC_TMPVAR_HANDLER, + ZEND_JMPNZ_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_JMPNZ_SPEC_CV_HANDLER, ZEND_JMPZ_EX_SPEC_CONST_HANDLER, - ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPZ_EX_SPEC_TMPVAR_HANDLER, + ZEND_JMPZ_EX_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_JMPZ_EX_SPEC_CV_HANDLER, ZEND_JMPNZ_EX_SPEC_CONST_HANDLER, - ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER, - ZEND_JMPNZ_EX_SPEC_TMPVAR_HANDLER, + ZEND_JMPNZ_EX_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_JMPNZ_EX_SPEC_CV_HANDLER, - ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER, - ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_CASE_SPEC_TMP_CONST_HANDLER, + ZEND_CASE_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_CASE_SPEC_TMPVAR_CV_HANDLER, + ZEND_CASE_SPEC_TMP_CV_HANDLER, ZEND_CHECK_VAR_SPEC_CV_UNUSED_HANDLER, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST_HANDLER, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST_HANDLER, @@ -123224,52 +117131,52 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_CAST_SPEC_CONST_HANDLER, ZEND_CAST_SPEC_TMP_HANDLER, - ZEND_CAST_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_CAST_SPEC_CV_HANDLER, ZEND_BOOL_SPEC_CONST_HANDLER, - ZEND_BOOL_SPEC_TMPVAR_HANDLER, - ZEND_BOOL_SPEC_TMPVAR_HANDLER, + ZEND_BOOL_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_BOOL_SPEC_CV_HANDLER, ZEND_FAST_CONCAT_SPEC_CONST_CONST_HANDLER, - ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER, - ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FAST_CONCAT_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FAST_CONCAT_SPEC_CONST_CV_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FAST_CONCAT_SPEC_TMP_CONST_HANDLER, + ZEND_FAST_CONCAT_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_FAST_CONCAT_SPEC_TMP_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FAST_CONCAT_SPEC_CV_CONST_HANDLER, - ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HANDLER, - ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_HANDLER, + ZEND_FAST_CONCAT_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FAST_CONCAT_SPEC_CV_CV_HANDLER, ZEND_ROPE_INIT_SPEC_UNUSED_CONST_HANDLER, - ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ROPE_INIT_SPEC_UNUSED_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ROPE_INIT_SPEC_UNUSED_CV_HANDLER, ZEND_ROPE_ADD_SPEC_TMP_CONST_HANDLER, - ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDLER, - ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_HANDLER, + ZEND_ROPE_ADD_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ROPE_ADD_SPEC_TMP_CV_HANDLER, ZEND_ROPE_END_SPEC_TMP_CONST_HANDLER, - ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDLER, - ZEND_ROPE_END_SPEC_TMP_TMPVAR_HANDLER, + ZEND_ROPE_END_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ROPE_END_SPEC_TMP_CV_HANDLER, ZEND_BEGIN_SILENCE_SPEC_HANDLER, @@ -123284,8 +117191,8 @@ void zend_vm_init(void) ZEND_RETURN_SPEC_OBSERVER_HANDLER, ZEND_RETURN_SPEC_TMP_HANDLER, ZEND_RETURN_SPEC_OBSERVER_HANDLER, - ZEND_RETURN_SPEC_VAR_HANDLER, - ZEND_RETURN_SPEC_OBSERVER_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_RETURN_SPEC_CV_HANDLER, @@ -123400,43 +117307,43 @@ void zend_vm_init(void) ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER, ZEND_FREE_SPEC_TMPVAR_HANDLER, ZEND_INIT_ARRAY_SPEC_CONST_CONST_HANDLER, - ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_HANDLER, - ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_HANDLER, + ZEND_INIT_ARRAY_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_HANDLER, ZEND_INIT_ARRAY_SPEC_CONST_CV_HANDLER, ZEND_INIT_ARRAY_SPEC_TMP_CONST_HANDLER, - ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HANDLER, - ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_HANDLER, + ZEND_INIT_ARRAY_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_HANDLER, ZEND_INIT_ARRAY_SPEC_TMP_CV_HANDLER, ZEND_INIT_ARRAY_SPEC_VAR_CONST_HANDLER, - ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER, - ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_HANDLER, + ZEND_INIT_ARRAY_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_HANDLER, ZEND_INIT_ARRAY_SPEC_VAR_CV_HANDLER, ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_HANDLER, - ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_INIT_ARRAY_SPEC_UNUSED_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_HANDLER, ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER, ZEND_INIT_ARRAY_SPEC_CV_CONST_HANDLER, - ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER, - ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_HANDLER, + ZEND_INIT_ARRAY_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_INIT_ARRAY_SPEC_CV_UNUSED_HANDLER, ZEND_INIT_ARRAY_SPEC_CV_CV_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER, ZEND_NULL_HANDLER, @@ -123445,18 +117352,18 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER, ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HANDLER, + ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_HANDLER, ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER, @@ -123475,8 +117382,8 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER, - ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER, - ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER, + ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER, ZEND_NULL_HANDLER, @@ -123485,8 +117392,8 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER, - ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER, - ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER, + ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER, ZEND_NULL_HANDLER, @@ -123500,44 +117407,44 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER, - ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER, - ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER, + ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER, ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER, - ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER, ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER, - ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_UNSET_OBJ_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER, ZEND_FE_RESET_R_SPEC_CONST_HANDLER, ZEND_FE_RESET_R_SPEC_TMP_HANDLER, - ZEND_FE_RESET_R_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FE_RESET_R_SPEC_CV_HANDLER, - ZEND_FE_FETCH_R_SPEC_VAR_HANDLER, + ZEND_FE_FETCH_R_SPEC_TMP_HANDLER, ZEND_FETCH_R_SPEC_CONST_UNUSED_HANDLER, - ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_FETCH_R_SPEC_TMP_UNUSED_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_R_SPEC_CV_UNUSED_HANDLER, ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER, - ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER, - ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER, ZEND_NULL_HANDLER, @@ -123546,38 +117453,38 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER, ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER, ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER, ZEND_FETCH_W_SPEC_CONST_UNUSED_HANDLER, - ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_FETCH_W_SPEC_TMP_UNUSED_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_W_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, @@ -123591,8 +117498,8 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER, ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER, ZEND_NULL_HANDLER, @@ -123601,8 +117508,8 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER, ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER, ZEND_NULL_HANDLER, @@ -123616,23 +117523,23 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER, ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER, ZEND_FETCH_RW_SPEC_CONST_UNUSED_HANDLER, - ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_FETCH_RW_SPEC_TMP_UNUSED_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_RW_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, @@ -123646,8 +117553,8 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER, ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER, ZEND_NULL_HANDLER, @@ -123656,8 +117563,8 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER, ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER, ZEND_NULL_HANDLER, @@ -123671,38 +117578,38 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER, ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER, ZEND_FETCH_IS_SPEC_CONST_UNUSED_HANDLER, - ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_FETCH_IS_SPEC_TMP_UNUSED_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_IS_SPEC_CV_UNUSED_HANDLER, ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_IS_SPEC_CONST_CV_HANDLER, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_HANDLER, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_HANDLER, ZEND_NULL_HANDLER, @@ -123711,53 +117618,53 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_IS_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_IS_SPEC_CV_CV_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER, ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER, ZEND_NULL_HANDLER, @@ -123766,38 +117673,38 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER, ZEND_FETCH_UNSET_SPEC_CONST_UNUSED_HANDLER, - ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_FETCH_UNSET_SPEC_TMP_UNUSED_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_UNSET_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, @@ -123811,8 +117718,8 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER, ZEND_NULL_HANDLER, @@ -123821,8 +117728,8 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER, ZEND_NULL_HANDLER, @@ -123836,33 +117743,33 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_HANDLER, + ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER, ZEND_FETCH_LIST_R_SPEC_CONST_CONST_HANDLER, - ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_HANDLER, - ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_HANDLER, + ZEND_FETCH_LIST_R_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_LIST_R_SPEC_CONST_CV_HANDLER, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_HANDLER, - ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER, - ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER, + ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_HANDLER, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_HANDLER, - ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER, - ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER, + ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_HANDLER, ZEND_NULL_HANDLER, @@ -123871,8 +117778,8 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_HANDLER, - ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER, - ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_HANDLER, + ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_HANDLER, ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER, @@ -123898,18 +117805,18 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_CATCH_SPEC_CONST_HANDLER, ZEND_THROW_SPEC_CONST_HANDLER, - ZEND_THROW_SPEC_TMPVAR_HANDLER, - ZEND_THROW_SPEC_TMPVAR_HANDLER, + ZEND_THROW_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_THROW_SPEC_CV_HANDLER, ZEND_FETCH_CLASS_SPEC_UNUSED_CONST_HANDLER, - ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_FETCH_CLASS_SPEC_UNUSED_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED_HANDLER, ZEND_FETCH_CLASS_SPEC_UNUSED_CV_HANDLER, ZEND_CLONE_SPEC_CONST_HANDLER, - ZEND_CLONE_SPEC_TMPVAR_HANDLER, - ZEND_CLONE_SPEC_TMPVAR_HANDLER, + ZEND_CLONE_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_CLONE_SPEC_UNUSED_HANDLER, ZEND_CLONE_SPEC_CV_HANDLER, ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER, @@ -123923,33 +117830,33 @@ void zend_vm_init(void) ZEND_RETURN_BY_REF_SPEC_CV_HANDLER, ZEND_RETURN_BY_REF_SPEC_OBSERVER_HANDLER, ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_INIT_METHOD_CALL_SPEC_CONST_CV_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER, ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER, ZEND_NULL_HANDLER, @@ -123958,13 +117865,13 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV_HANDLER, ZEND_NULL_HANDLER, @@ -123973,33 +117880,33 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER, ZEND_SEND_VAL_EX_SPEC_CONST_CONST_HANDLER, @@ -124078,25 +117985,25 @@ void zend_vm_init(void) ZEND_SEND_VAR_SPEC_CV_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_INIT_USER_CALL_SPEC_CONST_CONST_HANDLER, - ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER, - ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER, + ZEND_INIT_USER_CALL_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_INIT_USER_CALL_SPEC_CONST_CV_HANDLER, ZEND_SEND_ARRAY_SPEC_HANDLER, ZEND_SEND_USER_SPEC_CONST_HANDLER, ZEND_SEND_USER_SPEC_TMP_HANDLER, - ZEND_SEND_USER_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_SEND_USER_SPEC_CV_HANDLER, ZEND_STRLEN_SPEC_CONST_HANDLER, - ZEND_STRLEN_SPEC_TMPVAR_HANDLER, - ZEND_STRLEN_SPEC_TMPVAR_HANDLER, + ZEND_STRLEN_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_STRLEN_SPEC_CV_HANDLER, ZEND_DEFINED_SPEC_CONST_HANDLER, ZEND_TYPE_CHECK_SPEC_CONST_HANDLER, - ZEND_TYPE_CHECK_SPEC_TMPVAR_HANDLER, - ZEND_TYPE_CHECK_SPEC_TMPVAR_HANDLER, + ZEND_TYPE_CHECK_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_TYPE_CHECK_SPEC_CV_HANDLER, ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED_HANDLER, @@ -124112,8 +118019,8 @@ void zend_vm_init(void) ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER, ZEND_FE_FREE_SPEC_TMPVAR_HANDLER, ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER, ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER, @@ -124139,18 +118046,18 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_PRE_INC_OBJ_SPEC_VAR_CV_HANDLER, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_HANDLER, ZEND_PRE_INC_OBJ_SPEC_CV_CONST_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_PRE_INC_OBJ_SPEC_CV_CV_HANDLER, ZEND_NULL_HANDLER, @@ -124164,23 +118071,23 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_POST_INC_OBJ_SPEC_VAR_CONST_HANDLER, - ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER, - ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_HANDLER, + ZEND_POST_INC_OBJ_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_POST_INC_OBJ_SPEC_VAR_CV_HANDLER, ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_HANDLER, - ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_HANDLER, ZEND_POST_INC_OBJ_SPEC_CV_CONST_HANDLER, - ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_POST_INC_OBJ_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_POST_INC_OBJ_SPEC_CV_CV_HANDLER, ZEND_ECHO_SPEC_CONST_HANDLER, - ZEND_ECHO_SPEC_TMPVAR_HANDLER, - ZEND_ECHO_SPEC_TMPVAR_HANDLER, + ZEND_ECHO_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ECHO_SPEC_CV_HANDLER, ZEND_NULL_HANDLER, @@ -124189,15 +118096,15 @@ void zend_vm_init(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER, + ZEND_INSTANCEOF_SPEC_TMP_CONST_HANDLER, + ZEND_NULL_HANDLER, + ZEND_INSTANCEOF_SPEC_TMP_VAR_HANDLER, + ZEND_INSTANCEOF_SPEC_TMP_UNUSED_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER, - ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_HANDLER, ZEND_NULL_HANDLER, - ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_HANDLER, - ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, @@ -124223,28 +118130,28 @@ void zend_vm_init(void) ZEND_DECLARE_ANON_CLASS_SPEC_HANDLER, ZEND_ADD_ARRAY_UNPACK_SPEC_HANDLER, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_HANDLER, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_HANDLER, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER, ZEND_HANDLE_EXCEPTION_SPEC_HANDLER, @@ -124252,49 +118159,49 @@ void zend_vm_init(void) ZEND_ASSERT_CHECK_SPEC_HANDLER, ZEND_JMP_SET_SPEC_CONST_HANDLER, ZEND_JMP_SET_SPEC_TMP_HANDLER, - ZEND_JMP_SET_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_JMP_SET_SPEC_CV_HANDLER, ZEND_UNSET_CV_SPEC_CV_UNUSED_HANDLER, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET_HANDLER, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY_HANDLER, ZEND_FETCH_LIST_W_SPEC_VAR_CONST_HANDLER, - ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_HANDLER, - ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_HANDLER, + ZEND_FETCH_LIST_W_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_FETCH_LIST_W_SPEC_VAR_CV_HANDLER, ZEND_SEPARATE_SPEC_VAR_UNUSED_HANDLER, ZEND_NULL_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR_HANDLER, + ZEND_FETCH_CLASS_NAME_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_FETCH_CLASS_NAME_SPEC_UNUSED_HANDLER, ZEND_FETCH_CLASS_NAME_SPEC_CV_HANDLER, ZEND_CALL_TRAMPOLINE_SPEC_HANDLER, ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_HANDLER, ZEND_DISCARD_EXCEPTION_SPEC_HANDLER, ZEND_YIELD_SPEC_CONST_CONST_HANDLER, - ZEND_YIELD_SPEC_CONST_TMPVAR_HANDLER, - ZEND_YIELD_SPEC_CONST_TMPVAR_HANDLER, + ZEND_YIELD_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER, ZEND_YIELD_SPEC_CONST_CV_HANDLER, ZEND_YIELD_SPEC_TMP_CONST_HANDLER, - ZEND_YIELD_SPEC_TMP_TMPVAR_HANDLER, - ZEND_YIELD_SPEC_TMP_TMPVAR_HANDLER, + ZEND_YIELD_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER, ZEND_YIELD_SPEC_TMP_CV_HANDLER, ZEND_YIELD_SPEC_VAR_CONST_HANDLER, - ZEND_YIELD_SPEC_VAR_TMPVAR_HANDLER, - ZEND_YIELD_SPEC_VAR_TMPVAR_HANDLER, + ZEND_YIELD_SPEC_VAR_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER, ZEND_YIELD_SPEC_VAR_CV_HANDLER, ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER, - ZEND_YIELD_SPEC_UNUSED_TMPVAR_HANDLER, - ZEND_YIELD_SPEC_UNUSED_TMPVAR_HANDLER, + ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER, ZEND_YIELD_SPEC_UNUSED_CV_HANDLER, ZEND_YIELD_SPEC_CV_CONST_HANDLER, - ZEND_YIELD_SPEC_CV_TMPVAR_HANDLER, - ZEND_YIELD_SPEC_CV_TMPVAR_HANDLER, + ZEND_YIELD_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_YIELD_SPEC_CV_UNUSED_HANDLER, ZEND_YIELD_SPEC_CV_CV_HANDLER, ZEND_GENERATOR_RETURN_SPEC_CONST_HANDLER, @@ -124312,40 +118219,40 @@ void zend_vm_init(void) ZEND_RECV_VARIADIC_SPEC_UNUSED_HANDLER, ZEND_SEND_UNPACK_SPEC_HANDLER, ZEND_YIELD_FROM_SPEC_CONST_HANDLER, - ZEND_YIELD_FROM_SPEC_TMPVAR_HANDLER, - ZEND_YIELD_FROM_SPEC_TMPVAR_HANDLER, + ZEND_YIELD_FROM_SPEC_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_YIELD_FROM_SPEC_CV_HANDLER, ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_HANDLER, ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER, ZEND_COALESCE_SPEC_CONST_HANDLER, ZEND_COALESCE_SPEC_TMP_HANDLER, - ZEND_COALESCE_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_COALESCE_SPEC_CV_HANDLER, ZEND_SPACESHIP_SPEC_CONST_CONST_HANDLER, - ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER, - ZEND_SPACESHIP_SPEC_CONST_TMPVAR_HANDLER, + ZEND_SPACESHIP_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_SPACESHIP_SPEC_CONST_CV_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_SPACESHIP_SPEC_TMP_CONST_HANDLER, + ZEND_SPACESHIP_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_SPACESHIP_SPEC_TMP_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_CONST_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_SPACESHIP_SPEC_CV_CONST_HANDLER, - ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER, - ZEND_SPACESHIP_SPEC_CV_TMPVAR_HANDLER, + ZEND_SPACESHIP_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_SPACESHIP_SPEC_CV_CV_HANDLER, ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED_HANDLER, @@ -124408,48 +118315,48 @@ void zend_vm_init(void) ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST_HANDLER, ZEND_IN_ARRAY_SPEC_CONST_CONST_HANDLER, ZEND_IN_ARRAY_SPEC_TMP_CONST_HANDLER, - ZEND_IN_ARRAY_SPEC_VAR_CONST_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER, ZEND_COUNT_SPEC_CONST_UNUSED_HANDLER, - ZEND_COUNT_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_COUNT_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_COUNT_SPEC_TMP_UNUSED_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_COUNT_SPEC_CV_UNUSED_HANDLER, ZEND_GET_CLASS_SPEC_CONST_UNUSED_HANDLER, - ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_GET_CLASS_SPEC_TMP_UNUSED_HANDLER, + ZEND_NULL_HANDLER, ZEND_GET_CLASS_SPEC_UNUSED_UNUSED_HANDLER, ZEND_GET_CLASS_SPEC_CV_UNUSED_HANDLER, ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED_HANDLER, ZEND_GET_TYPE_SPEC_CONST_UNUSED_HANDLER, ZEND_GET_TYPE_SPEC_TMP_UNUSED_HANDLER, - ZEND_GET_TYPE_SPEC_VAR_UNUSED_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_GET_TYPE_SPEC_CV_UNUSED_HANDLER, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR_HANDLER, + ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_HANDLER, + ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST_HANDLER, + ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR_HANDLER, + ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_HANDLER, ZEND_MATCH_SPEC_CONST_CONST_HANDLER, @@ -124457,31 +118364,11 @@ void zend_vm_init(void) ZEND_MATCH_SPEC_TMPVARCV_CONST_HANDLER, ZEND_NULL_HANDLER, ZEND_MATCH_SPEC_TMPVARCV_CONST_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, ZEND_CASE_STRICT_SPEC_TMP_CONST_HANDLER, ZEND_CASE_STRICT_SPEC_TMP_TMP_HANDLER, - ZEND_CASE_STRICT_SPEC_TMP_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CASE_STRICT_SPEC_TMP_CV_HANDLER, - ZEND_CASE_STRICT_SPEC_VAR_CONST_HANDLER, - ZEND_CASE_STRICT_SPEC_VAR_TMP_HANDLER, - ZEND_CASE_STRICT_SPEC_VAR_VAR_HANDLER, - ZEND_NULL_HANDLER, - ZEND_CASE_STRICT_SPEC_VAR_CV_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, + ZEND_CASE_STRICT_SPEC_TMP_CV_HANDLER, ZEND_MATCH_ERROR_SPEC_CONST_UNUSED_HANDLER, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_HANDLER, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_HANDLER, @@ -124489,7 +118376,7 @@ void zend_vm_init(void) ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_HANDLER, ZEND_JMP_NULL_SPEC_CONST_HANDLER, ZEND_JMP_NULL_SPEC_TMP_HANDLER, - ZEND_JMP_NULL_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_JMP_NULL_SPEC_CV_HANDLER, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_HANDLER, @@ -124508,11 +118395,12 @@ void zend_vm_init(void) ZEND_JMP_FRAMELESS_SPEC_CONST_HANDLER, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_HANDLER, ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST_HANDLER, + ZEND_DEREF_SPEC_VAR_UNUSED_HANDLER, ZEND_INIT_FCALL_OFFSET_SPEC_CONST_HANDLER, ZEND_RECV_NOTYPE_SPEC_HANDLER, ZEND_NULL_HANDLER, - ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED_HANDLER, - ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED_HANDLER, + ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED_HANDLER, + ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED_HANDLER, ZEND_JMP_FORWARD_SPEC_HANDLER, @@ -125504,28 +119392,28 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_MUL_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER, ZEND_DIV_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_DIV_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_DIV_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_DIV_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_DIV_SPEC_CONST_CV_TAILCALL_HANDLER, - ZEND_DIV_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_DIV_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_DIV_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_DIV_SPEC_TMP_CONST_TAILCALL_HANDLER, + ZEND_DIV_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_DIV_SPEC_TMP_CV_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_DIV_SPEC_TMPVAR_CV_TAILCALL_HANDLER, - ZEND_DIV_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_DIV_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_DIV_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_DIV_SPEC_TMPVAR_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_DIV_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_DIV_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_DIV_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_DIV_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_DIV_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_MOD_SPEC_CONST_CONST_TAILCALL_HANDLER, @@ -125604,28 +119492,28 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_SR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_CONCAT_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_CONCAT_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_CONCAT_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_CONCAT_SPEC_CONST_CV_TAILCALL_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_CONCAT_SPEC_TMP_CONST_TAILCALL_HANDLER, + ZEND_CONCAT_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_CONCAT_SPEC_TMP_CV_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_CV_TAILCALL_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_CONCAT_SPEC_TMPVAR_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_CONCAT_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_CONCAT_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_CONCAT_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_CONCAT_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_CONCAT_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_BW_OR_SPEC_CONST_CONST_TAILCALL_HANDLER, @@ -125704,28 +119592,28 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV_TAILCALL_HANDLER, ZEND_POW_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_POW_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_POW_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_POW_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_POW_SPEC_CONST_CV_TAILCALL_HANDLER, - ZEND_POW_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_POW_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_POW_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_POW_SPEC_TMP_CONST_TAILCALL_HANDLER, + ZEND_POW_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_POW_SPEC_TMP_CV_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_POW_SPEC_TMPVAR_CV_TAILCALL_HANDLER, - ZEND_POW_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_POW_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_POW_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_POW_SPEC_TMPVAR_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_POW_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_POW_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_POW_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_POW_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_POW_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_BW_NOT_SPEC_CONST_TAILCALL_HANDLER, @@ -125734,8 +119622,8 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_BW_NOT_SPEC_TMPVARCV_TAILCALL_HANDLER, ZEND_BOOL_NOT_SPEC_CONST_TAILCALL_HANDLER, - ZEND_BOOL_NOT_SPEC_TMPVAR_TAILCALL_HANDLER, - ZEND_BOOL_NOT_SPEC_TMPVAR_TAILCALL_HANDLER, + ZEND_BOOL_NOT_SPEC_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_BOOL_NOT_SPEC_CV_TAILCALL_HANDLER, ZEND_BOOL_XOR_SPEC_CONST_CONST_TAILCALL_HANDLER, @@ -125743,14 +119631,14 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_BOOL_XOR_SPEC_TMP_CONST_TAILCALL_HANDLER, + ZEND_BOOL_XOR_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_BOOL_XOR_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -125759,8 +119647,8 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_BOOL_XOR_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_BOOL_XOR_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_BOOL_XOR_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_BOOL_XOR_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_BOOL_XOR_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_IS_IDENTICAL_SPEC_CONST_CONST_TAILCALL_HANDLER, @@ -125773,9 +119661,9 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_IS_IDENTICAL_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_IS_IDENTICAL_SPEC_VAR_TMP_TAILCALL_HANDLER, - ZEND_IS_IDENTICAL_SPEC_VAR_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -125785,7 +119673,7 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_IS_IDENTICAL_SPEC_CV_CONST_TAILCALL_HANDLER, ZEND_IS_IDENTICAL_SPEC_CV_TMP_TAILCALL_HANDLER, - ZEND_IS_IDENTICAL_SPEC_CV_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_IS_IDENTICAL_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST_TAILCALL_HANDLER, @@ -125798,9 +119686,9 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_TAILCALL_HANDLER, - ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -125810,7 +119698,7 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST_TAILCALL_HANDLER, ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_TAILCALL_HANDLER, - ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_IS_EQUAL_SPEC_CONST_CONST_TAILCALL_HANDLER, @@ -125828,30 +119716,30 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_TAILCALL_HANDLER, + ZEND_IS_EQUAL_SPEC_TMP_CONST_TAILCALL_HANDLER, + ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ_TAILCALL_HANDLER, + ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ_TAILCALL_HANDLER, + ZEND_IS_EQUAL_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ_TAILCALL_HANDLER, + ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -125876,12 +119764,12 @@ void zend_vm_init(void) ZEND_IS_EQUAL_SPEC_CV_CONST_TAILCALL_HANDLER, ZEND_IS_EQUAL_SPEC_CV_CONST_JMPZ_TAILCALL_HANDLER, ZEND_IS_EQUAL_SPEC_CV_CONST_JMPNZ_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ_TAILCALL_HANDLER, - ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ_TAILCALL_HANDLER, + ZEND_IS_EQUAL_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ_TAILCALL_HANDLER, + ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -125903,30 +119791,30 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_TAILCALL_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_TAILCALL_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ_TAILCALL_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ_TAILCALL_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ_TAILCALL_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -125951,12 +119839,12 @@ void zend_vm_init(void) ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_TAILCALL_HANDLER, ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPZ_TAILCALL_HANDLER, ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPNZ_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ_TAILCALL_HANDLER, - ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ_TAILCALL_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ_TAILCALL_HANDLER, + ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -126137,8 +120025,8 @@ void zend_vm_init(void) ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_USED_TAILCALL_HANDLER, ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED_TAILCALL_HANDLER, ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED_TAILCALL_HANDLER, - ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED_TAILCALL_HANDLER, - ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_UNUSED_TAILCALL_HANDLER, @@ -126157,8 +120045,8 @@ void zend_vm_init(void) ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_USED_TAILCALL_HANDLER, ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED_TAILCALL_HANDLER, ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED_TAILCALL_HANDLER, - ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED_TAILCALL_HANDLER, - ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSED_TAILCALL_HANDLER, @@ -126215,27 +120103,27 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST_TAILCALL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CONST_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CONST_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -126265,27 +120153,27 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST_TAILCALL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -126340,19 +120228,19 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -126360,24 +120248,24 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -126385,24 +120273,24 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -126410,12 +120298,12 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_TAILCALL_HANDLER, ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CONST_TAILCALL_HANDLER, ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_TMP_TAILCALL_HANDLER, - ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -126429,8 +120317,8 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OP_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_ASSIGN_OP_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OP_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -126439,8 +120327,8 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OP_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_ASSIGN_OP_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_ASSIGN_OP_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_ASSIGN_OP_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OP_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -126454,8 +120342,8 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -126464,8 +120352,8 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_ASSIGN_DIM_OP_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -126479,18 +120367,18 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CONST_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CV_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_OP_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_ASSIGN_STATIC_PROP_OP_SPEC_TAILCALL_HANDLER, @@ -126581,14 +120469,14 @@ void zend_vm_init(void) ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -126606,14 +120494,14 @@ void zend_vm_init(void) ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -126631,14 +120519,14 @@ void zend_vm_init(void) ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -126684,30 +120572,30 @@ void zend_vm_init(void) ZEND_POST_INC_STATIC_PROP_SPEC_TAILCALL_HANDLER, ZEND_JMP_SPEC_TAILCALL_HANDLER, ZEND_JMPZ_SPEC_CONST_TAILCALL_HANDLER, - ZEND_JMPZ_SPEC_TMPVAR_TAILCALL_HANDLER, - ZEND_JMPZ_SPEC_TMPVAR_TAILCALL_HANDLER, + ZEND_JMPZ_SPEC_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_JMPZ_SPEC_CV_TAILCALL_HANDLER, ZEND_JMPNZ_SPEC_CONST_TAILCALL_HANDLER, - ZEND_JMPNZ_SPEC_TMPVAR_TAILCALL_HANDLER, - ZEND_JMPNZ_SPEC_TMPVAR_TAILCALL_HANDLER, + ZEND_JMPNZ_SPEC_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_JMPNZ_SPEC_CV_TAILCALL_HANDLER, ZEND_JMPZ_EX_SPEC_CONST_TAILCALL_HANDLER, - ZEND_JMPZ_EX_SPEC_TMPVAR_TAILCALL_HANDLER, - ZEND_JMPZ_EX_SPEC_TMPVAR_TAILCALL_HANDLER, + ZEND_JMPZ_EX_SPEC_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_JMPZ_EX_SPEC_CV_TAILCALL_HANDLER, ZEND_JMPNZ_EX_SPEC_CONST_TAILCALL_HANDLER, - ZEND_JMPNZ_EX_SPEC_TMPVAR_TAILCALL_HANDLER, - ZEND_JMPNZ_EX_SPEC_TMPVAR_TAILCALL_HANDLER, + ZEND_JMPNZ_EX_SPEC_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_JMPNZ_EX_SPEC_CV_TAILCALL_HANDLER, - ZEND_CASE_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_CASE_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_CASE_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_CASE_SPEC_TMP_CONST_TAILCALL_HANDLER, + ZEND_CASE_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_CASE_SPEC_TMPVAR_CV_TAILCALL_HANDLER, + ZEND_CASE_SPEC_TMP_CV_TAILCALL_HANDLER, ZEND_CHECK_VAR_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST_TAILCALL_HANDLER, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST_TAILCALL_HANDLER, @@ -126721,52 +120609,52 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_CAST_SPEC_CONST_TAILCALL_HANDLER, ZEND_CAST_SPEC_TMP_TAILCALL_HANDLER, - ZEND_CAST_SPEC_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_CAST_SPEC_CV_TAILCALL_HANDLER, ZEND_BOOL_SPEC_CONST_TAILCALL_HANDLER, - ZEND_BOOL_SPEC_TMPVAR_TAILCALL_HANDLER, - ZEND_BOOL_SPEC_TMPVAR_TAILCALL_HANDLER, + ZEND_BOOL_SPEC_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_BOOL_SPEC_CV_TAILCALL_HANDLER, ZEND_FAST_CONCAT_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_FAST_CONCAT_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FAST_CONCAT_SPEC_CONST_CV_TAILCALL_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FAST_CONCAT_SPEC_TMP_CONST_TAILCALL_HANDLER, + ZEND_FAST_CONCAT_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_FAST_CONCAT_SPEC_TMP_CV_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_TAILCALL_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_FAST_CONCAT_SPEC_TMPVAR_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FAST_CONCAT_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_FAST_CONCAT_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_FAST_CONCAT_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FAST_CONCAT_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_ROPE_INIT_SPEC_UNUSED_CONST_TAILCALL_HANDLER, - ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, - ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, + ZEND_ROPE_INIT_SPEC_UNUSED_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ROPE_INIT_SPEC_UNUSED_CV_TAILCALL_HANDLER, ZEND_ROPE_ADD_SPEC_TMP_CONST_TAILCALL_HANDLER, - ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_TAILCALL_HANDLER, - ZEND_ROPE_ADD_SPEC_TMP_TMPVAR_TAILCALL_HANDLER, + ZEND_ROPE_ADD_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ROPE_ADD_SPEC_TMP_CV_TAILCALL_HANDLER, ZEND_ROPE_END_SPEC_TMP_CONST_TAILCALL_HANDLER, - ZEND_ROPE_END_SPEC_TMP_TMPVAR_TAILCALL_HANDLER, - ZEND_ROPE_END_SPEC_TMP_TMPVAR_TAILCALL_HANDLER, + ZEND_ROPE_END_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ROPE_END_SPEC_TMP_CV_TAILCALL_HANDLER, ZEND_BEGIN_SILENCE_SPEC_TAILCALL_HANDLER, @@ -126781,8 +120669,8 @@ void zend_vm_init(void) ZEND_RETURN_SPEC_OBSERVER_TAILCALL_HANDLER, ZEND_RETURN_SPEC_TMP_TAILCALL_HANDLER, ZEND_RETURN_SPEC_OBSERVER_TAILCALL_HANDLER, - ZEND_RETURN_SPEC_VAR_TAILCALL_HANDLER, - ZEND_RETURN_SPEC_OBSERVER_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_RETURN_SPEC_CV_TAILCALL_HANDLER, @@ -126897,43 +120785,43 @@ void zend_vm_init(void) ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_TAILCALL_HANDLER, ZEND_FREE_SPEC_TMPVAR_TAILCALL_HANDLER, ZEND_INIT_ARRAY_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_INIT_ARRAY_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_INIT_ARRAY_SPEC_CONST_UNUSED_TAILCALL_HANDLER, ZEND_INIT_ARRAY_SPEC_CONST_CV_TAILCALL_HANDLER, ZEND_INIT_ARRAY_SPEC_TMP_CONST_TAILCALL_HANDLER, - ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_TAILCALL_HANDLER, - ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR_TAILCALL_HANDLER, + ZEND_INIT_ARRAY_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_INIT_ARRAY_SPEC_TMP_UNUSED_TAILCALL_HANDLER, ZEND_INIT_ARRAY_SPEC_TMP_CV_TAILCALL_HANDLER, ZEND_INIT_ARRAY_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_INIT_ARRAY_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_INIT_ARRAY_SPEC_VAR_UNUSED_TAILCALL_HANDLER, ZEND_INIT_ARRAY_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_INIT_ARRAY_SPEC_UNUSED_CONST_TAILCALL_HANDLER, - ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, - ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, + ZEND_INIT_ARRAY_SPEC_UNUSED_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER, ZEND_INIT_ARRAY_SPEC_UNUSED_CV_TAILCALL_HANDLER, ZEND_INIT_ARRAY_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_INIT_ARRAY_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_INIT_ARRAY_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_INIT_ARRAY_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_INIT_ARRAY_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_TAILCALL_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_TAILCALL_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_TAILCALL_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_TAILCALL_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_TAILCALL_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_TAILCALL_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_TAILCALL_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_TAILCALL_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -126942,18 +120830,18 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_INCLUDE_OR_EVAL_SPEC_CONST_TAILCALL_HANDLER, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_TAILCALL_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_TAILCALL_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_TAILCALL_HANDLER, - ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_TAILCALL_HANDLER, + ZEND_INCLUDE_OR_EVAL_SPEC_TMP_TAILCALL_HANDLER, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_INCLUDE_OR_EVAL_SPEC_CV_TAILCALL_HANDLER, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER_TAILCALL_HANDLER, ZEND_UNSET_VAR_SPEC_CONST_UNUSED_TAILCALL_HANDLER, @@ -126972,8 +120860,8 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_UNSET_DIM_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_UNSET_DIM_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_UNSET_DIM_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -126982,8 +120870,8 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_UNSET_DIM_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_UNSET_DIM_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_UNSET_DIM_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_UNSET_DIM_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_UNSET_DIM_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -126997,44 +120885,44 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_UNSET_OBJ_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_UNSET_OBJ_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_UNSET_OBJ_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_TAILCALL_HANDLER, - ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, - ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, + ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_UNSET_OBJ_SPEC_UNUSED_CV_TAILCALL_HANDLER, ZEND_UNSET_OBJ_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_UNSET_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_UNSET_OBJ_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_FE_RESET_R_SPEC_CONST_TAILCALL_HANDLER, ZEND_FE_RESET_R_SPEC_TMP_TAILCALL_HANDLER, - ZEND_FE_RESET_R_SPEC_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FE_RESET_R_SPEC_CV_TAILCALL_HANDLER, - ZEND_FE_FETCH_R_SPEC_VAR_TAILCALL_HANDLER, + ZEND_FE_FETCH_R_SPEC_TMP_TAILCALL_HANDLER, ZEND_FETCH_R_SPEC_CONST_UNUSED_TAILCALL_HANDLER, - ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, - ZEND_FETCH_R_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, + ZEND_FETCH_R_SPEC_TMP_UNUSED_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_R_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_FETCH_DIM_R_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_R_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_R_SPEC_CONST_CV_TAILCALL_HANDLER, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127043,38 +120931,38 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_R_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_R_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_R_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_R_SPEC_CONST_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_R_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_R_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_R_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_FETCH_W_SPEC_CONST_UNUSED_TAILCALL_HANDLER, - ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, - ZEND_FETCH_W_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, + ZEND_FETCH_W_SPEC_TMP_UNUSED_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_W_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127088,8 +120976,8 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_W_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_W_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_TAILCALL_HANDLER, ZEND_FETCH_DIM_W_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127098,8 +120986,8 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_W_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_W_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_FETCH_DIM_W_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127113,23 +121001,23 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_W_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_W_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_W_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_W_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_FETCH_RW_SPEC_CONST_UNUSED_TAILCALL_HANDLER, - ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, - ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, + ZEND_FETCH_RW_SPEC_TMP_UNUSED_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_RW_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127143,8 +121031,8 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_TAILCALL_HANDLER, ZEND_FETCH_DIM_RW_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127153,8 +121041,8 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_RW_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_RW_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_FETCH_DIM_RW_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127168,38 +121056,38 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_RW_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_FETCH_IS_SPEC_CONST_UNUSED_TAILCALL_HANDLER, - ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, - ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, + ZEND_FETCH_IS_SPEC_TMP_UNUSED_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_IS_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_FETCH_DIM_IS_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_IS_SPEC_CONST_CV_TAILCALL_HANDLER, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_TAILCALL_HANDLER, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127208,53 +121096,53 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_IS_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_IS_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_IS_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_IS_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED_TAILCALL_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, - ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, + ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_TAILCALL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_TAILCALL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_TAILCALL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_TAILCALL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_TAILCALL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127263,38 +121151,38 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_FETCH_UNSET_SPEC_CONST_UNUSED_TAILCALL_HANDLER, - ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, - ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, + ZEND_FETCH_UNSET_SPEC_TMP_UNUSED_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_UNSET_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127308,8 +121196,8 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127318,8 +121206,8 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127333,33 +121221,33 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_TAILCALL_HANDLER, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_FETCH_LIST_R_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_LIST_R_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_LIST_R_SPEC_CONST_CV_TAILCALL_HANDLER, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER, - ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_TAILCALL_HANDLER, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER, - ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127368,8 +121256,8 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER, - ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV_TAILCALL_HANDLER, ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_TAILCALL_HANDLER, @@ -127395,18 +121283,18 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_CATCH_SPEC_CONST_TAILCALL_HANDLER, ZEND_THROW_SPEC_CONST_TAILCALL_HANDLER, - ZEND_THROW_SPEC_TMPVAR_TAILCALL_HANDLER, - ZEND_THROW_SPEC_TMPVAR_TAILCALL_HANDLER, + ZEND_THROW_SPEC_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_THROW_SPEC_CV_TAILCALL_HANDLER, ZEND_FETCH_CLASS_SPEC_UNUSED_CONST_TAILCALL_HANDLER, - ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_CLASS_SPEC_UNUSED_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER, ZEND_FETCH_CLASS_SPEC_UNUSED_CV_TAILCALL_HANDLER, ZEND_CLONE_SPEC_CONST_TAILCALL_HANDLER, - ZEND_CLONE_SPEC_TMPVAR_TAILCALL_HANDLER, - ZEND_CLONE_SPEC_TMPVAR_TAILCALL_HANDLER, + ZEND_CLONE_SPEC_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_CLONE_SPEC_UNUSED_TAILCALL_HANDLER, ZEND_CLONE_SPEC_CV_TAILCALL_HANDLER, ZEND_RETURN_BY_REF_SPEC_CONST_TAILCALL_HANDLER, @@ -127420,33 +121308,33 @@ void zend_vm_init(void) ZEND_RETURN_BY_REF_SPEC_CV_TAILCALL_HANDLER, ZEND_RETURN_BY_REF_SPEC_OBSERVER_TAILCALL_HANDLER, ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_INIT_METHOD_CALL_SPEC_CONST_CV_TAILCALL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_TAILCALL_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_TAILCALL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_TAILCALL_HANDLER, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_TAILCALL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_TAILCALL_HANDLER, ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_INIT_METHOD_CALL_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED_TAILCALL_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127455,13 +121343,13 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED_TAILCALL_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST_TAILCALL_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, - ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, + ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127470,33 +121358,33 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, + ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST_TAILCALL_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_SEND_VAL_EX_SPEC_CONST_CONST_TAILCALL_HANDLER, @@ -127575,25 +121463,25 @@ void zend_vm_init(void) ZEND_SEND_VAR_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_INIT_USER_CALL_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_INIT_USER_CALL_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_INIT_USER_CALL_SPEC_CONST_CV_TAILCALL_HANDLER, ZEND_SEND_ARRAY_SPEC_TAILCALL_HANDLER, ZEND_SEND_USER_SPEC_CONST_TAILCALL_HANDLER, ZEND_SEND_USER_SPEC_TMP_TAILCALL_HANDLER, - ZEND_SEND_USER_SPEC_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_SEND_USER_SPEC_CV_TAILCALL_HANDLER, ZEND_STRLEN_SPEC_CONST_TAILCALL_HANDLER, - ZEND_STRLEN_SPEC_TMPVAR_TAILCALL_HANDLER, - ZEND_STRLEN_SPEC_TMPVAR_TAILCALL_HANDLER, + ZEND_STRLEN_SPEC_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_STRLEN_SPEC_CV_TAILCALL_HANDLER, ZEND_DEFINED_SPEC_CONST_TAILCALL_HANDLER, ZEND_TYPE_CHECK_SPEC_CONST_TAILCALL_HANDLER, - ZEND_TYPE_CHECK_SPEC_TMPVAR_TAILCALL_HANDLER, - ZEND_TYPE_CHECK_SPEC_TMPVAR_TAILCALL_HANDLER, + ZEND_TYPE_CHECK_SPEC_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_TYPE_CHECK_SPEC_CV_TAILCALL_HANDLER, ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED_TAILCALL_HANDLER, @@ -127609,8 +121497,8 @@ void zend_vm_init(void) ZEND_FE_FETCH_RW_SPEC_VAR_TAILCALL_HANDLER, ZEND_FE_FREE_SPEC_TMPVAR_TAILCALL_HANDLER, ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_TAILCALL_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_TAILCALL_HANDLER, - ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_TAILCALL_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_INIT_DYNAMIC_CALL_SPEC_CV_TAILCALL_HANDLER, ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_TAILCALL_HANDLER, @@ -127636,18 +121524,18 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_PRE_INC_OBJ_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_TAILCALL_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_TAILCALL_HANDLER, ZEND_PRE_INC_OBJ_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_PRE_INC_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_PRE_INC_OBJ_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127661,23 +121549,23 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_POST_INC_OBJ_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_POST_INC_OBJ_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_POST_INC_OBJ_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST_TAILCALL_HANDLER, - ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, - ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, + ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_TAILCALL_HANDLER, ZEND_POST_INC_OBJ_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_POST_INC_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_POST_INC_OBJ_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_ECHO_SPEC_CONST_TAILCALL_HANDLER, - ZEND_ECHO_SPEC_TMPVAR_TAILCALL_HANDLER, - ZEND_ECHO_SPEC_TMPVAR_TAILCALL_HANDLER, + ZEND_ECHO_SPEC_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ECHO_SPEC_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127686,15 +121574,15 @@ void zend_vm_init(void) ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, + ZEND_INSTANCEOF_SPEC_TMP_CONST_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_INSTANCEOF_SPEC_TMP_VAR_TAILCALL_HANDLER, + ZEND_INSTANCEOF_SPEC_TMP_UNUSED_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_TAILCALL_HANDLER, - ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_INSTANCEOF_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_INSTANCEOF_SPEC_TMPVAR_VAR_TAILCALL_HANDLER, - ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -127720,28 +121608,28 @@ void zend_vm_init(void) ZEND_DECLARE_ANON_CLASS_SPEC_TAILCALL_HANDLER, ZEND_ADD_ARRAY_UNPACK_SPEC_TAILCALL_HANDLER, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_TAILCALL_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_TAILCALL_HANDLER, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_TAILCALL_HANDLER, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_HANDLE_EXCEPTION_SPEC_TAILCALL_HANDLER, @@ -127749,49 +121637,49 @@ void zend_vm_init(void) ZEND_ASSERT_CHECK_SPEC_TAILCALL_HANDLER, ZEND_JMP_SET_SPEC_CONST_TAILCALL_HANDLER, ZEND_JMP_SET_SPEC_TMP_TAILCALL_HANDLER, - ZEND_JMP_SET_SPEC_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_JMP_SET_SPEC_CV_TAILCALL_HANDLER, ZEND_UNSET_CV_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET_TAILCALL_HANDLER, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY_TAILCALL_HANDLER, ZEND_FETCH_LIST_W_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_LIST_W_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_LIST_W_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_SEPARATE_SPEC_VAR_UNUSED_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR_TAILCALL_HANDLER, - ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR_TAILCALL_HANDLER, + ZEND_FETCH_CLASS_NAME_SPEC_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_FETCH_CLASS_NAME_SPEC_UNUSED_TAILCALL_HANDLER, ZEND_FETCH_CLASS_NAME_SPEC_CV_TAILCALL_HANDLER, ZEND_CALL_TRAMPOLINE_SPEC_TAILCALL_HANDLER, ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_TAILCALL_HANDLER, ZEND_DISCARD_EXCEPTION_SPEC_TAILCALL_HANDLER, ZEND_YIELD_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_YIELD_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_YIELD_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_YIELD_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_YIELD_SPEC_CONST_UNUSED_TAILCALL_HANDLER, ZEND_YIELD_SPEC_CONST_CV_TAILCALL_HANDLER, ZEND_YIELD_SPEC_TMP_CONST_TAILCALL_HANDLER, - ZEND_YIELD_SPEC_TMP_TMPVAR_TAILCALL_HANDLER, - ZEND_YIELD_SPEC_TMP_TMPVAR_TAILCALL_HANDLER, + ZEND_YIELD_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_YIELD_SPEC_TMP_UNUSED_TAILCALL_HANDLER, ZEND_YIELD_SPEC_TMP_CV_TAILCALL_HANDLER, ZEND_YIELD_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_YIELD_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, - ZEND_YIELD_SPEC_VAR_TMPVAR_TAILCALL_HANDLER, + ZEND_YIELD_SPEC_VAR_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_YIELD_SPEC_VAR_UNUSED_TAILCALL_HANDLER, ZEND_YIELD_SPEC_VAR_CV_TAILCALL_HANDLER, ZEND_YIELD_SPEC_UNUSED_CONST_TAILCALL_HANDLER, - ZEND_YIELD_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, - ZEND_YIELD_SPEC_UNUSED_TMPVAR_TAILCALL_HANDLER, + ZEND_YIELD_SPEC_UNUSED_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_YIELD_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER, ZEND_YIELD_SPEC_UNUSED_CV_TAILCALL_HANDLER, ZEND_YIELD_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_YIELD_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_YIELD_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_YIELD_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_YIELD_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_YIELD_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_GENERATOR_RETURN_SPEC_CONST_TAILCALL_HANDLER, @@ -127809,40 +121697,40 @@ void zend_vm_init(void) ZEND_RECV_VARIADIC_SPEC_UNUSED_TAILCALL_HANDLER, ZEND_SEND_UNPACK_SPEC_TAILCALL_HANDLER, ZEND_YIELD_FROM_SPEC_CONST_TAILCALL_HANDLER, - ZEND_YIELD_FROM_SPEC_TMPVAR_TAILCALL_HANDLER, - ZEND_YIELD_FROM_SPEC_TMPVAR_TAILCALL_HANDLER, + ZEND_YIELD_FROM_SPEC_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_YIELD_FROM_SPEC_CV_TAILCALL_HANDLER, ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, ZEND_BIND_GLOBAL_SPEC_CV_CONST_TAILCALL_HANDLER, ZEND_COALESCE_SPEC_CONST_TAILCALL_HANDLER, ZEND_COALESCE_SPEC_TMP_TAILCALL_HANDLER, - ZEND_COALESCE_SPEC_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_COALESCE_SPEC_CV_TAILCALL_HANDLER, ZEND_SPACESHIP_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_SPACESHIP_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_SPACESHIP_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_SPACESHIP_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_SPACESHIP_SPEC_CONST_CV_TAILCALL_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_SPACESHIP_SPEC_TMP_CONST_TAILCALL_HANDLER, + ZEND_SPACESHIP_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_SPACESHIP_SPEC_TMP_CV_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_CV_TAILCALL_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_SPACESHIP_SPEC_TMPVAR_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_SPACESHIP_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_SPACESHIP_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_SPACESHIP_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_SPACESHIP_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_SPACESHIP_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER, @@ -127905,48 +121793,48 @@ void zend_vm_init(void) ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER, ZEND_IN_ARRAY_SPEC_CONST_CONST_TAILCALL_HANDLER, ZEND_IN_ARRAY_SPEC_TMP_CONST_TAILCALL_HANDLER, - ZEND_IN_ARRAY_SPEC_VAR_CONST_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_IN_ARRAY_SPEC_CV_CONST_TAILCALL_HANDLER, ZEND_COUNT_SPEC_CONST_UNUSED_TAILCALL_HANDLER, - ZEND_COUNT_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, - ZEND_COUNT_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, + ZEND_COUNT_SPEC_TMP_UNUSED_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_COUNT_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_GET_CLASS_SPEC_CONST_UNUSED_TAILCALL_HANDLER, - ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, - ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, + ZEND_GET_CLASS_SPEC_TMP_UNUSED_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_GET_CLASS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER, ZEND_GET_CLASS_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER, ZEND_GET_TYPE_SPEC_CONST_UNUSED_TAILCALL_HANDLER, ZEND_GET_TYPE_SPEC_TMP_UNUSED_TAILCALL_HANDLER, - ZEND_GET_TYPE_SPEC_VAR_UNUSED_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_GET_TYPE_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR_TAILCALL_HANDLER, + ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV_TAILCALL_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, + ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST_TAILCALL_HANDLER, + ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV_TAILCALL_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST_TAILCALL_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST_TAILCALL_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR_TAILCALL_HANDLER, - ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR_TAILCALL_HANDLER, + ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV_TAILCALL_HANDLER, ZEND_MATCH_SPEC_CONST_CONST_TAILCALL_HANDLER, @@ -127954,31 +121842,11 @@ void zend_vm_init(void) ZEND_MATCH_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_MATCH_SPEC_TMPVARCV_CONST_TAILCALL_HANDLER, - ZEND_NULL_TAILCALL_HANDLER, - ZEND_NULL_TAILCALL_HANDLER, - ZEND_NULL_TAILCALL_HANDLER, - ZEND_NULL_TAILCALL_HANDLER, - ZEND_NULL_TAILCALL_HANDLER, ZEND_CASE_STRICT_SPEC_TMP_CONST_TAILCALL_HANDLER, ZEND_CASE_STRICT_SPEC_TMP_TMP_TAILCALL_HANDLER, - ZEND_CASE_STRICT_SPEC_TMP_VAR_TAILCALL_HANDLER, - ZEND_NULL_TAILCALL_HANDLER, - ZEND_CASE_STRICT_SPEC_TMP_CV_TAILCALL_HANDLER, - ZEND_CASE_STRICT_SPEC_VAR_CONST_TAILCALL_HANDLER, - ZEND_CASE_STRICT_SPEC_VAR_TMP_TAILCALL_HANDLER, - ZEND_CASE_STRICT_SPEC_VAR_VAR_TAILCALL_HANDLER, - ZEND_NULL_TAILCALL_HANDLER, - ZEND_CASE_STRICT_SPEC_VAR_CV_TAILCALL_HANDLER, - ZEND_NULL_TAILCALL_HANDLER, - ZEND_NULL_TAILCALL_HANDLER, - ZEND_NULL_TAILCALL_HANDLER, - ZEND_NULL_TAILCALL_HANDLER, - ZEND_NULL_TAILCALL_HANDLER, - ZEND_NULL_TAILCALL_HANDLER, - ZEND_NULL_TAILCALL_HANDLER, - ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, + ZEND_CASE_STRICT_SPEC_TMP_CV_TAILCALL_HANDLER, ZEND_MATCH_ERROR_SPEC_CONST_UNUSED_TAILCALL_HANDLER, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_TAILCALL_HANDLER, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_TAILCALL_HANDLER, @@ -127986,7 +121854,7 @@ void zend_vm_init(void) ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED_TAILCALL_HANDLER, ZEND_JMP_NULL_SPEC_CONST_TAILCALL_HANDLER, ZEND_JMP_NULL_SPEC_TMP_TAILCALL_HANDLER, - ZEND_JMP_NULL_SPEC_VAR_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_JMP_NULL_SPEC_CV_TAILCALL_HANDLER, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED_TAILCALL_HANDLER, @@ -128005,11 +121873,12 @@ void zend_vm_init(void) ZEND_JMP_FRAMELESS_SPEC_CONST_TAILCALL_HANDLER, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_TAILCALL_HANDLER, ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST_TAILCALL_HANDLER, + ZEND_DEREF_SPEC_VAR_UNUSED_TAILCALL_HANDLER, ZEND_INIT_FCALL_OFFSET_SPEC_CONST_TAILCALL_HANDLER, ZEND_RECV_NOTYPE_SPEC_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, - ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, - ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED_TAILCALL_HANDLER, + ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED_TAILCALL_HANDLER, + ZEND_NULL_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED_TAILCALL_HANDLER, ZEND_JMP_FORWARD_SPEC_TAILCALL_HANDLER, @@ -128973,7 +122842,7 @@ void zend_vm_init(void) 1255, 1256 | SPEC_RULE_OP1, 1261 | SPEC_RULE_OP1, - 3493, + 3474, 1266 | SPEC_RULE_OP1, 1271 | SPEC_RULE_OP1, 1276 | SPEC_RULE_OP2, @@ -129007,7 +122876,7 @@ void zend_vm_init(void) 1559 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1584 | SPEC_RULE_OP1, 1589, - 3493, + 3474, 1590 | SPEC_RULE_OP1, 1595 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1620 | SPEC_RULE_OP1 | SPEC_RULE_OP2, @@ -129124,66 +122993,66 @@ void zend_vm_init(void) 2492 | SPEC_RULE_OP1, 2497 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 2522 | SPEC_RULE_OP1, - 2527 | SPEC_RULE_OP1 | SPEC_RULE_OP2, - 2552 | SPEC_RULE_OP1, - 2557 | SPEC_RULE_OP1, - 2562, - 2563, - 2564, - 2565, - 2566, - 2567 | SPEC_RULE_OBSERVER, - 2569 | SPEC_RULE_OBSERVER, - 2571 | SPEC_RULE_OBSERVER, - 2573 | SPEC_RULE_OBSERVER, - 2575, - 2576, - 2577, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, - 3493, + 2527 | SPEC_RULE_OP2, + 2532 | SPEC_RULE_OP1, + 2537 | SPEC_RULE_OP1, + 2542, + 2543, + 2544, + 2545, + 2546, + 2547 | SPEC_RULE_OBSERVER, + 2549 | SPEC_RULE_OBSERVER, + 2551 | SPEC_RULE_OBSERVER, + 2553 | SPEC_RULE_OBSERVER, + 2555, + 2556, + 2557, + 2558, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, + 3474, }; #if 0 #elif (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) @@ -129360,7 +123229,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2586 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2567 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -129368,7 +123237,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2611 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2592 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -129376,7 +123245,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2636 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2617 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -129387,17 +123256,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2661 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2642 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2686 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2667 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2711 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2692 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_MUL: @@ -129408,17 +123277,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2736 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2717 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2761 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2742 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2786 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2767 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_IDENTICAL: @@ -129429,16 +123298,16 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2811 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2792 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2886 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2867 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op2_type == IS_CONST && (Z_TYPE_P(RT_CONSTANT(op, op->op2)) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(RT_CONSTANT(op, op->op2))) == 0)) { - spec = 3111 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3092 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) { - spec = 3117 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3098 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_IDENTICAL: @@ -129449,16 +123318,16 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2961 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2942 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3036 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3017 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op2_type == IS_CONST && (Z_TYPE_P(RT_CONSTANT(op, op->op2)) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(RT_CONSTANT(op, op->op2))) == 0)) { - spec = 3114 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3095 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) { - spec = 3122 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3103 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_EQUAL: @@ -129469,12 +123338,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2811 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2792 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2886 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2867 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_EQUAL: @@ -129485,12 +123354,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2961 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2942 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3036 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3017 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_SMALLER: @@ -129498,12 +123367,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3127 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3108 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3202 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3183 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_IS_SMALLER_OR_EQUAL: @@ -129511,79 +123380,79 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3277 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3258 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3352 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3333 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_QM_ASSIGN: if (op1_info == MAY_BE_LONG) { - spec = 3439 | SPEC_RULE_OP1; + spec = 3420 | SPEC_RULE_OP1; } else if (op1_info == MAY_BE_DOUBLE) { - spec = 3444 | SPEC_RULE_OP1; + spec = 3425 | SPEC_RULE_OP1; } else if ((op->op1_type == IS_CONST) ? !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1)) : (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE))))) { - spec = 3449 | SPEC_RULE_OP1; + spec = 3430 | SPEC_RULE_OP1; } break; case ZEND_PRE_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3427 | SPEC_RULE_RETVAL; + spec = 3408 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3429 | SPEC_RULE_RETVAL; + spec = 3410 | SPEC_RULE_RETVAL; } break; case ZEND_PRE_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3431 | SPEC_RULE_RETVAL; + spec = 3412 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3433 | SPEC_RULE_RETVAL; + spec = 3414 | SPEC_RULE_RETVAL; } break; case ZEND_POST_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3435; + spec = 3416; } else if (op1_info == MAY_BE_LONG) { - spec = 3436; + spec = 3417; } break; case ZEND_POST_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3437; + spec = 3418; } else if (op1_info == MAY_BE_LONG) { - spec = 3438; + spec = 3419; } break; case ZEND_JMP: if (OP_JMP_ADDR(op, op->op1) > op) { - spec = 2585; + spec = 2566; } break; case ZEND_INIT_FCALL: if (Z_EXTRA_P(RT_CONSTANT(op, op->op2)) != 0) { - spec = 2578; + spec = 2559; } break; case ZEND_RECV: if (op->op2.num == MAY_BE_ANY) { - spec = 2579; + spec = 2560; } break; case ZEND_SEND_VAL: if (op->op1_type == IS_CONST && op->op2_type == IS_UNUSED && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { - spec = 3489; + spec = 3470; } break; case ZEND_SEND_VAR_EX: if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3484 | SPEC_RULE_OP1; + spec = 3465 | SPEC_RULE_OP1; } break; case ZEND_FE_FETCH_R: if (op->op2_type == IS_CV && (op1_info & (MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) { - spec = 3491 | SPEC_RULE_RETVAL; + spec = 3472 | SPEC_RULE_RETVAL; } break; case ZEND_FETCH_DIM_R: @@ -129591,22 +123460,22 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3454 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3435 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_SEND_VAL_EX: if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { - spec = 3490; + spec = 3471; } break; case ZEND_SEND_VAR: if (op->op2_type == IS_UNUSED && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3479 | SPEC_RULE_OP1; + spec = 3460 | SPEC_RULE_OP1; } break; case ZEND_COUNT: if ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) == MAY_BE_ARRAY) { - spec = 2580 | SPEC_RULE_OP1; + spec = 2561 | SPEC_RULE_OP1; } break; case ZEND_BW_OR: diff --git a/Zend/zend_vm_handlers.h b/Zend/zend_vm_handlers.h index 33d951141550e..16db986c334c3 100644 --- a/Zend/zend_vm_handlers.h +++ b/Zend/zend_vm_handlers.h @@ -46,20 +46,13 @@ _(73, ZEND_MUL_SPEC_TMPVARCV_TMPVARCV) \ _(75, ZEND_MUL_SPEC_TMPVARCV_TMPVARCV) \ _(76, ZEND_DIV_SPEC_CONST_CONST) \ - _(77, ZEND_DIV_SPEC_CONST_TMPVAR) \ - _(78, ZEND_DIV_SPEC_CONST_TMPVAR) \ + _(77, ZEND_DIV_SPEC_CONST_TMP) \ _(80, ZEND_DIV_SPEC_CONST_CV) \ - _(81, ZEND_DIV_SPEC_TMPVAR_CONST) \ - _(82, ZEND_DIV_SPEC_TMPVAR_TMPVAR) \ - _(83, ZEND_DIV_SPEC_TMPVAR_TMPVAR) \ - _(85, ZEND_DIV_SPEC_TMPVAR_CV) \ - _(86, ZEND_DIV_SPEC_TMPVAR_CONST) \ - _(87, ZEND_DIV_SPEC_TMPVAR_TMPVAR) \ - _(88, ZEND_DIV_SPEC_TMPVAR_TMPVAR) \ - _(90, ZEND_DIV_SPEC_TMPVAR_CV) \ + _(81, ZEND_DIV_SPEC_TMP_CONST) \ + _(82, ZEND_DIV_SPEC_TMP_TMP) \ + _(85, ZEND_DIV_SPEC_TMP_CV) \ _(96, ZEND_DIV_SPEC_CV_CONST) \ - _(97, ZEND_DIV_SPEC_CV_TMPVAR) \ - _(98, ZEND_DIV_SPEC_CV_TMPVAR) \ + _(97, ZEND_DIV_SPEC_CV_TMP) \ _(100, ZEND_DIV_SPEC_CV_CV) \ _(101, ZEND_MOD_SPEC_CONST_CONST) \ _(102, ZEND_MOD_SPEC_CONST_TMPVARCV) \ @@ -109,20 +102,13 @@ _(172, ZEND_SR_SPEC_TMPVARCV_TMPVARCV) \ _(173, ZEND_SR_SPEC_TMPVARCV_TMPVARCV) \ _(175, ZEND_SR_SPEC_TMPVARCV_TMPVARCV) \ - _(177, ZEND_CONCAT_SPEC_CONST_TMPVAR) \ - _(178, ZEND_CONCAT_SPEC_CONST_TMPVAR) \ + _(177, ZEND_CONCAT_SPEC_CONST_TMP) \ _(180, ZEND_CONCAT_SPEC_CONST_CV) \ - _(181, ZEND_CONCAT_SPEC_TMPVAR_CONST) \ - _(182, ZEND_CONCAT_SPEC_TMPVAR_TMPVAR) \ - _(183, ZEND_CONCAT_SPEC_TMPVAR_TMPVAR) \ - _(185, ZEND_CONCAT_SPEC_TMPVAR_CV) \ - _(186, ZEND_CONCAT_SPEC_TMPVAR_CONST) \ - _(187, ZEND_CONCAT_SPEC_TMPVAR_TMPVAR) \ - _(188, ZEND_CONCAT_SPEC_TMPVAR_TMPVAR) \ - _(190, ZEND_CONCAT_SPEC_TMPVAR_CV) \ + _(181, ZEND_CONCAT_SPEC_TMP_CONST) \ + _(182, ZEND_CONCAT_SPEC_TMP_TMP) \ + _(185, ZEND_CONCAT_SPEC_TMP_CV) \ _(196, ZEND_CONCAT_SPEC_CV_CONST) \ - _(197, ZEND_CONCAT_SPEC_CV_TMPVAR) \ - _(198, ZEND_CONCAT_SPEC_CV_TMPVAR) \ + _(197, ZEND_CONCAT_SPEC_CV_TMP) \ _(200, ZEND_CONCAT_SPEC_CV_CV) \ _(201, ZEND_BW_OR_SPEC_CONST_CONST) \ _(206, ZEND_BW_OR_SPEC_TMPVARCV_CONST) \ @@ -164,123 +150,72 @@ _(273, ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV) \ _(275, ZEND_BW_XOR_SPEC_TMPVARCV_TMPVARCV) \ _(276, ZEND_POW_SPEC_CONST_CONST) \ - _(277, ZEND_POW_SPEC_CONST_TMPVAR) \ - _(278, ZEND_POW_SPEC_CONST_TMPVAR) \ + _(277, ZEND_POW_SPEC_CONST_TMP) \ _(280, ZEND_POW_SPEC_CONST_CV) \ - _(281, ZEND_POW_SPEC_TMPVAR_CONST) \ - _(282, ZEND_POW_SPEC_TMPVAR_TMPVAR) \ - _(283, ZEND_POW_SPEC_TMPVAR_TMPVAR) \ - _(285, ZEND_POW_SPEC_TMPVAR_CV) \ - _(286, ZEND_POW_SPEC_TMPVAR_CONST) \ - _(287, ZEND_POW_SPEC_TMPVAR_TMPVAR) \ - _(288, ZEND_POW_SPEC_TMPVAR_TMPVAR) \ - _(290, ZEND_POW_SPEC_TMPVAR_CV) \ + _(281, ZEND_POW_SPEC_TMP_CONST) \ + _(282, ZEND_POW_SPEC_TMP_TMP) \ + _(285, ZEND_POW_SPEC_TMP_CV) \ _(296, ZEND_POW_SPEC_CV_CONST) \ - _(297, ZEND_POW_SPEC_CV_TMPVAR) \ - _(298, ZEND_POW_SPEC_CV_TMPVAR) \ + _(297, ZEND_POW_SPEC_CV_TMP) \ _(300, ZEND_POW_SPEC_CV_CV) \ _(301, ZEND_BW_NOT_SPEC_CONST) \ _(302, ZEND_BW_NOT_SPEC_TMPVARCV) \ _(303, ZEND_BW_NOT_SPEC_TMPVARCV) \ _(305, ZEND_BW_NOT_SPEC_TMPVARCV) \ _(306, ZEND_BOOL_NOT_SPEC_CONST) \ - _(307, ZEND_BOOL_NOT_SPEC_TMPVAR) \ - _(308, ZEND_BOOL_NOT_SPEC_TMPVAR) \ + _(307, ZEND_BOOL_NOT_SPEC_TMP) \ _(310, ZEND_BOOL_NOT_SPEC_CV) \ _(311, ZEND_BOOL_XOR_SPEC_CONST_CONST) \ - _(316, ZEND_BOOL_XOR_SPEC_TMPVAR_CONST) \ - _(317, ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR) \ - _(318, ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR) \ - _(321, ZEND_BOOL_XOR_SPEC_TMPVAR_CONST) \ - _(322, ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR) \ - _(323, ZEND_BOOL_XOR_SPEC_TMPVAR_TMPVAR) \ + _(316, ZEND_BOOL_XOR_SPEC_TMP_CONST) \ + _(317, ZEND_BOOL_XOR_SPEC_TMP_TMP) \ _(331, ZEND_BOOL_XOR_SPEC_CV_CONST) \ - _(332, ZEND_BOOL_XOR_SPEC_CV_TMPVAR) \ - _(333, ZEND_BOOL_XOR_SPEC_CV_TMPVAR) \ + _(332, ZEND_BOOL_XOR_SPEC_CV_TMP) \ _(335, ZEND_BOOL_XOR_SPEC_CV_CV) \ _(336, ZEND_IS_IDENTICAL_SPEC_CONST_CONST) \ _(341, ZEND_IS_IDENTICAL_SPEC_TMP_CONST) \ _(342, ZEND_IS_IDENTICAL_SPEC_TMP_TMP) \ - _(346, ZEND_IS_IDENTICAL_SPEC_VAR_CONST) \ - _(347, ZEND_IS_IDENTICAL_SPEC_VAR_TMP) \ - _(348, ZEND_IS_IDENTICAL_SPEC_VAR_VAR) \ _(356, ZEND_IS_IDENTICAL_SPEC_CV_CONST) \ _(357, ZEND_IS_IDENTICAL_SPEC_CV_TMP) \ - _(358, ZEND_IS_IDENTICAL_SPEC_CV_VAR) \ _(360, ZEND_IS_IDENTICAL_SPEC_CV_CV) \ _(361, ZEND_IS_NOT_IDENTICAL_SPEC_CONST_CONST) \ _(366, ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST) \ _(367, ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP) \ - _(371, ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST) \ - _(372, ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP) \ - _(373, ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR) \ _(381, ZEND_IS_NOT_IDENTICAL_SPEC_CV_CONST) \ _(382, ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP) \ - _(383, ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR) \ _(385, ZEND_IS_NOT_IDENTICAL_SPEC_CV_CV) \ _(386, ZEND_IS_EQUAL_SPEC_CONST_CONST) \ _(387, ZEND_IS_EQUAL_SPEC_CONST_CONST) \ _(388, ZEND_IS_EQUAL_SPEC_CONST_CONST) \ - _(401, ZEND_IS_EQUAL_SPEC_TMPVAR_CONST) \ - _(402, ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ) \ - _(403, ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ) \ - _(404, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR) \ - _(405, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) \ - _(406, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) \ - _(407, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR) \ - _(408, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) \ - _(409, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) \ - _(416, ZEND_IS_EQUAL_SPEC_TMPVAR_CONST) \ - _(417, ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPZ) \ - _(418, ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_JMPNZ) \ - _(419, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR) \ - _(420, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) \ - _(421, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) \ - _(422, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR) \ - _(423, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) \ - _(424, ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) \ + _(401, ZEND_IS_EQUAL_SPEC_TMP_CONST) \ + _(402, ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPZ) \ + _(403, ZEND_IS_EQUAL_SPEC_TMP_CONST_JMPNZ) \ + _(404, ZEND_IS_EQUAL_SPEC_TMP_TMP) \ + _(405, ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPZ) \ + _(406, ZEND_IS_EQUAL_SPEC_TMP_TMP_JMPNZ) \ _(446, ZEND_IS_EQUAL_SPEC_CV_CONST) \ _(447, ZEND_IS_EQUAL_SPEC_CV_CONST_JMPZ) \ _(448, ZEND_IS_EQUAL_SPEC_CV_CONST_JMPNZ) \ - _(449, ZEND_IS_EQUAL_SPEC_CV_TMPVAR) \ - _(450, ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ) \ - _(451, ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ) \ - _(452, ZEND_IS_EQUAL_SPEC_CV_TMPVAR) \ - _(453, ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPZ) \ - _(454, ZEND_IS_EQUAL_SPEC_CV_TMPVAR_JMPNZ) \ + _(449, ZEND_IS_EQUAL_SPEC_CV_TMP) \ + _(450, ZEND_IS_EQUAL_SPEC_CV_TMP_JMPZ) \ + _(451, ZEND_IS_EQUAL_SPEC_CV_TMP_JMPNZ) \ _(458, ZEND_IS_EQUAL_SPEC_CV_CV) \ _(459, ZEND_IS_EQUAL_SPEC_CV_CV_JMPZ) \ _(460, ZEND_IS_EQUAL_SPEC_CV_CV_JMPNZ) \ _(461, ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST) \ _(462, ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST) \ _(463, ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST) \ - _(476, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST) \ - _(477, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ) \ - _(478, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ) \ - _(479, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR) \ - _(480, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) \ - _(481, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) \ - _(482, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR) \ - _(483, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) \ - _(484, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) \ - _(491, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST) \ - _(492, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPZ) \ - _(493, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST_JMPNZ) \ - _(494, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR) \ - _(495, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) \ - _(496, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) \ - _(497, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR) \ - _(498, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPZ) \ - _(499, ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVAR_JMPNZ) \ + _(476, ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST) \ + _(477, ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPZ) \ + _(478, ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_JMPNZ) \ + _(479, ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP) \ + _(480, ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPZ) \ + _(481, ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_JMPNZ) \ _(521, ZEND_IS_NOT_EQUAL_SPEC_CV_CONST) \ _(522, ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPZ) \ _(523, ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_JMPNZ) \ - _(524, ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR) \ - _(525, ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ) \ - _(526, ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ) \ - _(527, ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR) \ - _(528, ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPZ) \ - _(529, ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_JMPNZ) \ + _(524, ZEND_IS_NOT_EQUAL_SPEC_CV_TMP) \ + _(525, ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPZ) \ + _(526, ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_JMPNZ) \ _(533, ZEND_IS_NOT_EQUAL_SPEC_CV_CV) \ _(534, ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPZ) \ _(535, ZEND_IS_NOT_EQUAL_SPEC_CV_CV_JMPNZ) \ @@ -384,139 +319,90 @@ _(707, ZEND_ASSIGN_SPEC_VAR_CONST_RETVAL_USED) \ _(708, ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_UNUSED) \ _(709, ZEND_ASSIGN_SPEC_VAR_TMP_RETVAL_USED) \ - _(710, ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_UNUSED) \ - _(711, ZEND_ASSIGN_SPEC_VAR_VAR_RETVAL_USED) \ _(714, ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_UNUSED) \ _(715, ZEND_ASSIGN_SPEC_VAR_CV_RETVAL_USED) \ _(726, ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_UNUSED) \ _(727, ZEND_ASSIGN_SPEC_CV_CONST_RETVAL_USED) \ _(728, ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_UNUSED) \ _(729, ZEND_ASSIGN_SPEC_CV_TMP_RETVAL_USED) \ - _(730, ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_UNUSED) \ - _(731, ZEND_ASSIGN_SPEC_CV_VAR_RETVAL_USED) \ _(734, ZEND_ASSIGN_SPEC_CV_CV_RETVAL_UNUSED) \ _(735, ZEND_ASSIGN_SPEC_CV_CV_RETVAL_USED) \ _(786, ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST) \ _(787, ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP) \ - _(788, ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR) \ _(790, ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV) \ - _(791, ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST) \ - _(792, ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP) \ - _(793, ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR) \ - _(795, ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV) \ - _(796, ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST) \ - _(797, ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP) \ - _(798, ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR) \ - _(800, ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV) \ + _(791, ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CONST) \ + _(792, ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_TMP) \ + _(795, ZEND_ASSIGN_DIM_SPEC_VAR_TMP_OP_DATA_CV) \ _(801, ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CONST) \ _(802, ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP) \ - _(803, ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR) \ _(805, ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV) \ _(806, ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CONST) \ _(807, ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP) \ - _(808, ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR) \ _(810, ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV) \ _(836, ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST) \ _(837, ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP) \ - _(838, ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR) \ _(840, ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV) \ - _(841, ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST) \ - _(842, ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP) \ - _(843, ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR) \ - _(845, ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV) \ - _(846, ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST) \ - _(847, ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP) \ - _(848, ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR) \ - _(850, ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV) \ + _(841, ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CONST) \ + _(842, ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_TMP) \ + _(845, ZEND_ASSIGN_DIM_SPEC_CV_TMP_OP_DATA_CV) \ _(851, ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST) \ _(852, ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP) \ - _(853, ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR) \ _(855, ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV) \ _(856, ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST) \ _(857, ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP) \ - _(858, ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR) \ _(860, ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV) \ _(911, ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST) \ _(912, ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP) \ - _(913, ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR) \ _(915, ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV) \ - _(916, ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST) \ - _(917, ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP) \ - _(918, ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR) \ - _(920, ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV) \ - _(921, ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST) \ - _(922, ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP) \ - _(923, ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR) \ - _(925, ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV) \ + _(916, ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CONST) \ + _(917, ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_TMP) \ + _(920, ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_OP_DATA_CV) \ _(931, ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST) \ _(932, ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP) \ - _(933, ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR) \ _(935, ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV) \ _(936, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST) \ _(937, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP) \ - _(938, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR) \ _(940, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV) \ - _(941, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST) \ - _(942, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP) \ - _(943, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR) \ - _(945, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV) \ - _(946, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST) \ - _(947, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP) \ - _(948, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR) \ - _(950, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV) \ + _(941, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CONST) \ + _(942, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_TMP) \ + _(945, ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_OP_DATA_CV) \ _(956, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST) \ _(957, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP) \ - _(958, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR) \ _(960, ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV) \ _(961, ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST) \ _(962, ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP) \ - _(963, ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR) \ _(965, ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV) \ - _(966, ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST) \ - _(967, ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP) \ - _(968, ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR) \ - _(970, ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV) \ - _(971, ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST) \ - _(972, ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP) \ - _(973, ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR) \ - _(975, ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV) \ + _(966, ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CONST) \ + _(967, ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_TMP) \ + _(970, ZEND_ASSIGN_OBJ_SPEC_CV_TMP_OP_DATA_CV) \ _(981, ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST) \ _(982, ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP) \ - _(983, ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR) \ _(985, ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV) \ _(986, ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CONST) \ _(987, ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_TMP) \ - _(988, ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_VAR) \ _(990, ZEND_ASSIGN_STATIC_PROP_SPEC_OP_DATA_CV) \ _(1001, ZEND_ASSIGN_OP_SPEC_VAR_CONST) \ - _(1002, ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR) \ - _(1003, ZEND_ASSIGN_OP_SPEC_VAR_TMPVAR) \ + _(1002, ZEND_ASSIGN_OP_SPEC_VAR_TMP) \ _(1005, ZEND_ASSIGN_OP_SPEC_VAR_CV) \ _(1011, ZEND_ASSIGN_OP_SPEC_CV_CONST) \ - _(1012, ZEND_ASSIGN_OP_SPEC_CV_TMPVAR) \ - _(1013, ZEND_ASSIGN_OP_SPEC_CV_TMPVAR) \ + _(1012, ZEND_ASSIGN_OP_SPEC_CV_TMP) \ _(1015, ZEND_ASSIGN_OP_SPEC_CV_CV) \ _(1026, ZEND_ASSIGN_DIM_OP_SPEC_VAR_CONST) \ - _(1027, ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR) \ - _(1028, ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMPVAR) \ + _(1027, ZEND_ASSIGN_DIM_OP_SPEC_VAR_TMP) \ _(1029, ZEND_ASSIGN_DIM_OP_SPEC_VAR_UNUSED) \ _(1030, ZEND_ASSIGN_DIM_OP_SPEC_VAR_CV) \ _(1036, ZEND_ASSIGN_DIM_OP_SPEC_CV_CONST) \ - _(1037, ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR) \ - _(1038, ZEND_ASSIGN_DIM_OP_SPEC_CV_TMPVAR) \ + _(1037, ZEND_ASSIGN_DIM_OP_SPEC_CV_TMP) \ _(1039, ZEND_ASSIGN_DIM_OP_SPEC_CV_UNUSED) \ _(1040, ZEND_ASSIGN_DIM_OP_SPEC_CV_CV) \ _(1051, ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST) \ - _(1052, ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR) \ - _(1053, ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR) \ + _(1052, ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMP) \ _(1055, ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV) \ _(1056, ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CONST) \ - _(1057, ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR) \ - _(1058, ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPVAR) \ + _(1057, ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMP) \ _(1060, ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CV) \ _(1061, ZEND_ASSIGN_OBJ_OP_SPEC_CV_CONST) \ - _(1062, ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR) \ - _(1063, ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR) \ + _(1062, ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMP) \ _(1065, ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV) \ _(1066, ZEND_ASSIGN_STATIC_PROP_OP_SPEC) \ _(1079, ZEND_ASSIGN_REF_SPEC_VAR_VAR) \ @@ -529,26 +415,20 @@ _(1096, ZEND_QM_ASSIGN_SPEC_CV) \ _(1149, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_VAR) \ _(1151, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CONST_OP_DATA_CV) \ - _(1154, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR) \ - _(1156, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV) \ - _(1159, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_VAR) \ - _(1161, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMPVAR_OP_DATA_CV) \ + _(1154, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_VAR) \ + _(1156, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_TMP_OP_DATA_CV) \ _(1169, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_DATA_VAR) \ _(1171, ZEND_ASSIGN_OBJ_REF_SPEC_VAR_CV_OP_DATA_CV) \ _(1174, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_VAR) \ _(1176, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CONST_OP_DATA_CV) \ - _(1179, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR) \ - _(1181, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV) \ - _(1184, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_VAR) \ - _(1186, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMPVAR_OP_DATA_CV) \ + _(1179, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_VAR) \ + _(1181, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_TMP_OP_DATA_CV) \ _(1194, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_VAR) \ _(1196, ZEND_ASSIGN_OBJ_REF_SPEC_UNUSED_CV_OP_DATA_CV) \ _(1199, ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_VAR) \ _(1201, ZEND_ASSIGN_OBJ_REF_SPEC_CV_CONST_OP_DATA_CV) \ - _(1204, ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR) \ - _(1206, ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV) \ - _(1209, ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_VAR) \ - _(1211, ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMPVAR_OP_DATA_CV) \ + _(1204, ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_VAR) \ + _(1206, ZEND_ASSIGN_OBJ_REF_SPEC_CV_TMP_OP_DATA_CV) \ _(1219, ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_VAR) \ _(1221, ZEND_ASSIGN_OBJ_REF_SPEC_CV_CV_OP_DATA_CV) \ _(1222, ZEND_ASSIGN_STATIC_PROP_REF_SPEC) \ @@ -568,25 +448,20 @@ _(1254, ZEND_POST_INC_STATIC_PROP_SPEC) \ _(1255, ZEND_JMP_SPEC) \ _(1256, ZEND_JMPZ_SPEC_CONST) \ - _(1257, ZEND_JMPZ_SPEC_TMPVAR) \ - _(1258, ZEND_JMPZ_SPEC_TMPVAR) \ + _(1257, ZEND_JMPZ_SPEC_TMP) \ _(1260, ZEND_JMPZ_SPEC_CV) \ _(1261, ZEND_JMPNZ_SPEC_CONST) \ - _(1262, ZEND_JMPNZ_SPEC_TMPVAR) \ - _(1263, ZEND_JMPNZ_SPEC_TMPVAR) \ + _(1262, ZEND_JMPNZ_SPEC_TMP) \ _(1265, ZEND_JMPNZ_SPEC_CV) \ _(1266, ZEND_JMPZ_EX_SPEC_CONST) \ - _(1267, ZEND_JMPZ_EX_SPEC_TMPVAR) \ - _(1268, ZEND_JMPZ_EX_SPEC_TMPVAR) \ + _(1267, ZEND_JMPZ_EX_SPEC_TMP) \ _(1270, ZEND_JMPZ_EX_SPEC_CV) \ _(1271, ZEND_JMPNZ_EX_SPEC_CONST) \ - _(1272, ZEND_JMPNZ_EX_SPEC_TMPVAR) \ - _(1273, ZEND_JMPNZ_EX_SPEC_TMPVAR) \ + _(1272, ZEND_JMPNZ_EX_SPEC_TMP) \ _(1275, ZEND_JMPNZ_EX_SPEC_CV) \ - _(1276, ZEND_CASE_SPEC_TMPVAR_CONST) \ - _(1277, ZEND_CASE_SPEC_TMPVAR_TMPVAR) \ - _(1278, ZEND_CASE_SPEC_TMPVAR_TMPVAR) \ - _(1280, ZEND_CASE_SPEC_TMPVAR_CV) \ + _(1276, ZEND_CASE_SPEC_TMP_CONST) \ + _(1277, ZEND_CASE_SPEC_TMP_TMP) \ + _(1280, ZEND_CASE_SPEC_TMP_CV) \ _(1281, ZEND_CHECK_VAR_SPEC_CV_UNUSED) \ _(1282, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST) \ _(1283, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_CONST) \ @@ -594,39 +469,27 @@ _(1289, ZEND_SEND_VAR_NO_REF_EX_SPEC_VAR_UNUSED_QUICK) \ _(1292, ZEND_CAST_SPEC_CONST) \ _(1293, ZEND_CAST_SPEC_TMP) \ - _(1294, ZEND_CAST_SPEC_VAR) \ _(1296, ZEND_CAST_SPEC_CV) \ _(1297, ZEND_BOOL_SPEC_CONST) \ - _(1298, ZEND_BOOL_SPEC_TMPVAR) \ - _(1299, ZEND_BOOL_SPEC_TMPVAR) \ + _(1298, ZEND_BOOL_SPEC_TMP) \ _(1301, ZEND_BOOL_SPEC_CV) \ _(1302, ZEND_FAST_CONCAT_SPEC_CONST_CONST) \ - _(1303, ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR) \ - _(1304, ZEND_FAST_CONCAT_SPEC_CONST_TMPVAR) \ + _(1303, ZEND_FAST_CONCAT_SPEC_CONST_TMP) \ _(1306, ZEND_FAST_CONCAT_SPEC_CONST_CV) \ - _(1307, ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST) \ - _(1308, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \ - _(1309, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \ - _(1311, ZEND_FAST_CONCAT_SPEC_TMPVAR_CV) \ - _(1312, ZEND_FAST_CONCAT_SPEC_TMPVAR_CONST) \ - _(1313, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \ - _(1314, ZEND_FAST_CONCAT_SPEC_TMPVAR_TMPVAR) \ - _(1316, ZEND_FAST_CONCAT_SPEC_TMPVAR_CV) \ + _(1307, ZEND_FAST_CONCAT_SPEC_TMP_CONST) \ + _(1308, ZEND_FAST_CONCAT_SPEC_TMP_TMP) \ + _(1311, ZEND_FAST_CONCAT_SPEC_TMP_CV) \ _(1322, ZEND_FAST_CONCAT_SPEC_CV_CONST) \ - _(1323, ZEND_FAST_CONCAT_SPEC_CV_TMPVAR) \ - _(1324, ZEND_FAST_CONCAT_SPEC_CV_TMPVAR) \ + _(1323, ZEND_FAST_CONCAT_SPEC_CV_TMP) \ _(1326, ZEND_FAST_CONCAT_SPEC_CV_CV) \ _(1327, ZEND_ROPE_INIT_SPEC_UNUSED_CONST) \ - _(1328, ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR) \ - _(1329, ZEND_ROPE_INIT_SPEC_UNUSED_TMPVAR) \ + _(1328, ZEND_ROPE_INIT_SPEC_UNUSED_TMP) \ _(1331, ZEND_ROPE_INIT_SPEC_UNUSED_CV) \ _(1332, ZEND_ROPE_ADD_SPEC_TMP_CONST) \ - _(1333, ZEND_ROPE_ADD_SPEC_TMP_TMPVAR) \ - _(1334, ZEND_ROPE_ADD_SPEC_TMP_TMPVAR) \ + _(1333, ZEND_ROPE_ADD_SPEC_TMP_TMP) \ _(1336, ZEND_ROPE_ADD_SPEC_TMP_CV) \ _(1337, ZEND_ROPE_END_SPEC_TMP_CONST) \ - _(1338, ZEND_ROPE_END_SPEC_TMP_TMPVAR) \ - _(1339, ZEND_ROPE_END_SPEC_TMP_TMPVAR) \ + _(1338, ZEND_ROPE_END_SPEC_TMP_TMP) \ _(1341, ZEND_ROPE_END_SPEC_TMP_CV) \ _(1342, ZEND_BEGIN_SILENCE_SPEC) \ _(1343, ZEND_END_SILENCE_SPEC_TMP) \ @@ -640,8 +503,6 @@ _(1351, ZEND_RETURN_SPEC_OBSERVER) \ _(1352, ZEND_RETURN_SPEC_TMP) \ _(1353, ZEND_RETURN_SPEC_OBSERVER) \ - _(1354, ZEND_RETURN_SPEC_VAR) \ - _(1355, ZEND_RETURN_SPEC_OBSERVER) \ _(1358, ZEND_RETURN_SPEC_CV) \ _(1359, ZEND_RETURN_SPEC_OBSERVER) \ _(1360, ZEND_RECV_SPEC_UNUSED) \ @@ -670,56 +531,45 @@ _(1467, ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST) \ _(1468, ZEND_FREE_SPEC_TMPVAR) \ _(1469, ZEND_INIT_ARRAY_SPEC_CONST_CONST) \ - _(1470, ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR) \ - _(1471, ZEND_INIT_ARRAY_SPEC_CONST_TMPVAR) \ + _(1470, ZEND_INIT_ARRAY_SPEC_CONST_TMP) \ _(1472, ZEND_INIT_ARRAY_SPEC_CONST_UNUSED) \ _(1473, ZEND_INIT_ARRAY_SPEC_CONST_CV) \ _(1474, ZEND_INIT_ARRAY_SPEC_TMP_CONST) \ - _(1475, ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR) \ - _(1476, ZEND_INIT_ARRAY_SPEC_TMP_TMPVAR) \ + _(1475, ZEND_INIT_ARRAY_SPEC_TMP_TMP) \ _(1477, ZEND_INIT_ARRAY_SPEC_TMP_UNUSED) \ _(1478, ZEND_INIT_ARRAY_SPEC_TMP_CV) \ _(1479, ZEND_INIT_ARRAY_SPEC_VAR_CONST) \ - _(1480, ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR) \ - _(1481, ZEND_INIT_ARRAY_SPEC_VAR_TMPVAR) \ + _(1480, ZEND_INIT_ARRAY_SPEC_VAR_TMP) \ _(1482, ZEND_INIT_ARRAY_SPEC_VAR_UNUSED) \ _(1483, ZEND_INIT_ARRAY_SPEC_VAR_CV) \ _(1484, ZEND_INIT_ARRAY_SPEC_UNUSED_CONST) \ - _(1485, ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR) \ - _(1486, ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR) \ + _(1485, ZEND_INIT_ARRAY_SPEC_UNUSED_TMP) \ _(1487, ZEND_INIT_ARRAY_SPEC_UNUSED_UNUSED) \ _(1488, ZEND_INIT_ARRAY_SPEC_UNUSED_CV) \ _(1489, ZEND_INIT_ARRAY_SPEC_CV_CONST) \ - _(1490, ZEND_INIT_ARRAY_SPEC_CV_TMPVAR) \ - _(1491, ZEND_INIT_ARRAY_SPEC_CV_TMPVAR) \ + _(1490, ZEND_INIT_ARRAY_SPEC_CV_TMP) \ _(1492, ZEND_INIT_ARRAY_SPEC_CV_UNUSED) \ _(1493, ZEND_INIT_ARRAY_SPEC_CV_CV) \ _(1494, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST) \ - _(1495, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR) \ - _(1496, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR) \ + _(1495, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP) \ _(1497, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED) \ _(1498, ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV) \ _(1499, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST) \ - _(1500, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR) \ - _(1501, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR) \ + _(1500, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP) \ _(1502, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED) \ _(1503, ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV) \ _(1504, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST) \ - _(1505, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR) \ - _(1506, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR) \ + _(1505, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP) \ _(1507, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED) \ _(1508, ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV) \ _(1514, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST) \ - _(1515, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR) \ - _(1516, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR) \ + _(1515, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP) \ _(1517, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED) \ _(1518, ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV) \ _(1519, ZEND_INCLUDE_OR_EVAL_SPEC_CONST) \ _(1520, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ - _(1521, ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR) \ + _(1521, ZEND_INCLUDE_OR_EVAL_SPEC_TMP) \ _(1522, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ - _(1523, ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR) \ - _(1524, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ _(1527, ZEND_INCLUDE_OR_EVAL_SPEC_CV) \ _(1528, ZEND_INCLUDE_OR_EVAL_SPEC_OBSERVER) \ _(1529, ZEND_UNSET_VAR_SPEC_CONST_UNUSED) \ @@ -727,245 +577,187 @@ _(1531, ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED) \ _(1533, ZEND_UNSET_VAR_SPEC_CV_UNUSED) \ _(1544, ZEND_UNSET_DIM_SPEC_VAR_CONST) \ - _(1545, ZEND_UNSET_DIM_SPEC_VAR_TMPVAR) \ - _(1546, ZEND_UNSET_DIM_SPEC_VAR_TMPVAR) \ + _(1545, ZEND_UNSET_DIM_SPEC_VAR_TMP) \ _(1548, ZEND_UNSET_DIM_SPEC_VAR_CV) \ _(1554, ZEND_UNSET_DIM_SPEC_CV_CONST) \ - _(1555, ZEND_UNSET_DIM_SPEC_CV_TMPVAR) \ - _(1556, ZEND_UNSET_DIM_SPEC_CV_TMPVAR) \ + _(1555, ZEND_UNSET_DIM_SPEC_CV_TMP) \ _(1558, ZEND_UNSET_DIM_SPEC_CV_CV) \ _(1569, ZEND_UNSET_OBJ_SPEC_VAR_CONST) \ - _(1570, ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR) \ - _(1571, ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR) \ + _(1570, ZEND_UNSET_OBJ_SPEC_VAR_TMP) \ _(1573, ZEND_UNSET_OBJ_SPEC_VAR_CV) \ _(1574, ZEND_UNSET_OBJ_SPEC_UNUSED_CONST) \ - _(1575, ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR) \ - _(1576, ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR) \ + _(1575, ZEND_UNSET_OBJ_SPEC_UNUSED_TMP) \ _(1578, ZEND_UNSET_OBJ_SPEC_UNUSED_CV) \ _(1579, ZEND_UNSET_OBJ_SPEC_CV_CONST) \ - _(1580, ZEND_UNSET_OBJ_SPEC_CV_TMPVAR) \ - _(1581, ZEND_UNSET_OBJ_SPEC_CV_TMPVAR) \ + _(1580, ZEND_UNSET_OBJ_SPEC_CV_TMP) \ _(1583, ZEND_UNSET_OBJ_SPEC_CV_CV) \ _(1584, ZEND_FE_RESET_R_SPEC_CONST) \ _(1585, ZEND_FE_RESET_R_SPEC_TMP) \ - _(1586, ZEND_FE_RESET_R_SPEC_VAR) \ _(1588, ZEND_FE_RESET_R_SPEC_CV) \ - _(1589, ZEND_FE_FETCH_R_SPEC_VAR) \ + _(1589, ZEND_FE_FETCH_R_SPEC_TMP) \ _(1590, ZEND_FETCH_R_SPEC_CONST_UNUSED) \ - _(1591, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) \ - _(1592, ZEND_FETCH_R_SPEC_TMPVAR_UNUSED) \ + _(1591, ZEND_FETCH_R_SPEC_TMP_UNUSED) \ _(1594, ZEND_FETCH_R_SPEC_CV_UNUSED) \ _(1595, ZEND_FETCH_DIM_R_SPEC_CONST_CONST) \ - _(1596, ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) \ - _(1597, ZEND_FETCH_DIM_R_SPEC_CONST_TMPVAR) \ + _(1596, ZEND_FETCH_DIM_R_SPEC_CONST_TMP) \ _(1599, ZEND_FETCH_DIM_R_SPEC_CONST_CV) \ _(1600, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) \ - _(1601, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ - _(1602, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ + _(1601, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP) \ _(1604, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) \ _(1605, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST) \ - _(1606, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ - _(1607, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMPVAR) \ + _(1606, ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP) \ _(1609, ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV) \ _(1615, ZEND_FETCH_DIM_R_SPEC_CV_CONST) \ - _(1616, ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) \ - _(1617, ZEND_FETCH_DIM_R_SPEC_CV_TMPVAR) \ + _(1616, ZEND_FETCH_DIM_R_SPEC_CV_TMP) \ _(1619, ZEND_FETCH_DIM_R_SPEC_CV_CV) \ _(1620, ZEND_FETCH_OBJ_R_SPEC_CONST_CONST) \ - _(1621, ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) \ - _(1622, ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR) \ + _(1621, ZEND_FETCH_OBJ_R_SPEC_CONST_TMP) \ _(1624, ZEND_FETCH_OBJ_R_SPEC_CONST_CV) \ _(1625, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST) \ - _(1626, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ - _(1627, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ + _(1626, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP) \ _(1629, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV) \ _(1630, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST) \ - _(1631, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ - _(1632, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR) \ + _(1631, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP) \ _(1634, ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV) \ _(1635, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST) \ - _(1636, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) \ - _(1637, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR) \ + _(1636, ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP) \ _(1639, ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV) \ _(1640, ZEND_FETCH_OBJ_R_SPEC_CV_CONST) \ - _(1641, ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) \ - _(1642, ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR) \ + _(1641, ZEND_FETCH_OBJ_R_SPEC_CV_TMP) \ _(1644, ZEND_FETCH_OBJ_R_SPEC_CV_CV) \ _(1645, ZEND_FETCH_W_SPEC_CONST_UNUSED) \ - _(1646, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) \ - _(1647, ZEND_FETCH_W_SPEC_TMPVAR_UNUSED) \ + _(1646, ZEND_FETCH_W_SPEC_TMP_UNUSED) \ _(1649, ZEND_FETCH_W_SPEC_CV_UNUSED) \ _(1660, ZEND_FETCH_DIM_W_SPEC_VAR_CONST) \ - _(1661, ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) \ - _(1662, ZEND_FETCH_DIM_W_SPEC_VAR_TMPVAR) \ + _(1661, ZEND_FETCH_DIM_W_SPEC_VAR_TMP) \ _(1663, ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED) \ _(1664, ZEND_FETCH_DIM_W_SPEC_VAR_CV) \ _(1670, ZEND_FETCH_DIM_W_SPEC_CV_CONST) \ - _(1671, ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) \ - _(1672, ZEND_FETCH_DIM_W_SPEC_CV_TMPVAR) \ + _(1671, ZEND_FETCH_DIM_W_SPEC_CV_TMP) \ _(1673, ZEND_FETCH_DIM_W_SPEC_CV_UNUSED) \ _(1674, ZEND_FETCH_DIM_W_SPEC_CV_CV) \ _(1685, ZEND_FETCH_OBJ_W_SPEC_VAR_CONST) \ - _(1686, ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) \ - _(1687, ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR) \ + _(1686, ZEND_FETCH_OBJ_W_SPEC_VAR_TMP) \ _(1689, ZEND_FETCH_OBJ_W_SPEC_VAR_CV) \ _(1690, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST) \ - _(1691, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) \ - _(1692, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR) \ + _(1691, ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP) \ _(1694, ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV) \ _(1695, ZEND_FETCH_OBJ_W_SPEC_CV_CONST) \ - _(1696, ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) \ - _(1697, ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR) \ + _(1696, ZEND_FETCH_OBJ_W_SPEC_CV_TMP) \ _(1699, ZEND_FETCH_OBJ_W_SPEC_CV_CV) \ _(1700, ZEND_FETCH_RW_SPEC_CONST_UNUSED) \ - _(1701, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) \ - _(1702, ZEND_FETCH_RW_SPEC_TMPVAR_UNUSED) \ + _(1701, ZEND_FETCH_RW_SPEC_TMP_UNUSED) \ _(1704, ZEND_FETCH_RW_SPEC_CV_UNUSED) \ _(1715, ZEND_FETCH_DIM_RW_SPEC_VAR_CONST) \ - _(1716, ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) \ - _(1717, ZEND_FETCH_DIM_RW_SPEC_VAR_TMPVAR) \ + _(1716, ZEND_FETCH_DIM_RW_SPEC_VAR_TMP) \ _(1718, ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED) \ _(1719, ZEND_FETCH_DIM_RW_SPEC_VAR_CV) \ _(1725, ZEND_FETCH_DIM_RW_SPEC_CV_CONST) \ - _(1726, ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) \ - _(1727, ZEND_FETCH_DIM_RW_SPEC_CV_TMPVAR) \ + _(1726, ZEND_FETCH_DIM_RW_SPEC_CV_TMP) \ _(1728, ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED) \ _(1729, ZEND_FETCH_DIM_RW_SPEC_CV_CV) \ _(1740, ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST) \ - _(1741, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) \ - _(1742, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR) \ + _(1741, ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP) \ _(1744, ZEND_FETCH_OBJ_RW_SPEC_VAR_CV) \ _(1745, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST) \ - _(1746, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) \ - _(1747, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR) \ + _(1746, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP) \ _(1749, ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV) \ _(1750, ZEND_FETCH_OBJ_RW_SPEC_CV_CONST) \ - _(1751, ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) \ - _(1752, ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR) \ + _(1751, ZEND_FETCH_OBJ_RW_SPEC_CV_TMP) \ _(1754, ZEND_FETCH_OBJ_RW_SPEC_CV_CV) \ _(1755, ZEND_FETCH_IS_SPEC_CONST_UNUSED) \ - _(1756, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) \ - _(1757, ZEND_FETCH_IS_SPEC_TMPVAR_UNUSED) \ + _(1756, ZEND_FETCH_IS_SPEC_TMP_UNUSED) \ _(1759, ZEND_FETCH_IS_SPEC_CV_UNUSED) \ _(1760, ZEND_FETCH_DIM_IS_SPEC_CONST_CONST) \ - _(1761, ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) \ - _(1762, ZEND_FETCH_DIM_IS_SPEC_CONST_TMPVAR) \ + _(1761, ZEND_FETCH_DIM_IS_SPEC_CONST_TMP) \ _(1764, ZEND_FETCH_DIM_IS_SPEC_CONST_CV) \ _(1765, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST) \ - _(1766, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ - _(1767, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ + _(1766, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP) \ _(1769, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV) \ _(1770, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CONST) \ - _(1771, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ - _(1772, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMPVAR) \ + _(1771, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_TMP) \ _(1774, ZEND_FETCH_DIM_IS_SPEC_TMPVAR_CV) \ _(1780, ZEND_FETCH_DIM_IS_SPEC_CV_CONST) \ - _(1781, ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) \ - _(1782, ZEND_FETCH_DIM_IS_SPEC_CV_TMPVAR) \ + _(1781, ZEND_FETCH_DIM_IS_SPEC_CV_TMP) \ _(1784, ZEND_FETCH_DIM_IS_SPEC_CV_CV) \ _(1785, ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST) \ - _(1786, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) \ - _(1787, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR) \ + _(1786, ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP) \ _(1789, ZEND_FETCH_OBJ_IS_SPEC_CONST_CV) \ _(1790, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST) \ - _(1791, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ - _(1792, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ + _(1791, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP) \ _(1794, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV) \ _(1795, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST) \ - _(1796, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ - _(1797, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR) \ + _(1796, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMP) \ _(1799, ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV) \ _(1800, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST) \ - _(1801, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) \ - _(1802, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR) \ + _(1801, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP) \ _(1804, ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV) \ _(1805, ZEND_FETCH_OBJ_IS_SPEC_CV_CONST) \ - _(1806, ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) \ - _(1807, ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR) \ + _(1806, ZEND_FETCH_OBJ_IS_SPEC_CV_TMP) \ _(1809, ZEND_FETCH_OBJ_IS_SPEC_CV_CV) \ _(1810, ZEND_FETCH_FUNC_ARG_SPEC_CONST_UNUSED) \ - _(1811, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) \ - _(1812, ZEND_FETCH_FUNC_ARG_SPEC_TMPVAR_UNUSED) \ + _(1811, ZEND_FETCH_FUNC_ARG_SPEC_TMP_UNUSED) \ _(1814, ZEND_FETCH_FUNC_ARG_SPEC_CV_UNUSED) \ _(1815, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST) \ - _(1816, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1817, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMPVAR) \ + _(1816, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP) \ _(1818, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED) \ _(1819, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV) \ _(1820, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST) \ - _(1821, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1822, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMPVAR) \ + _(1821, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP) \ _(1823, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED) \ _(1824, ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV) \ _(1825, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST) \ - _(1826, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1827, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMPVAR) \ + _(1826, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP) \ _(1828, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED) \ _(1829, ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV) \ _(1835, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST) \ - _(1836, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1837, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMPVAR) \ + _(1836, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP) \ _(1838, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED) \ _(1839, ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV) \ _(1840, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST) \ - _(1841, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) \ - _(1842, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR) \ + _(1841, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP) \ _(1844, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV) \ _(1845, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST) \ - _(1846, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) \ - _(1847, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR) \ + _(1846, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP) \ _(1849, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV) \ _(1850, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST) \ - _(1851, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) \ - _(1852, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR) \ + _(1851, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP) \ _(1854, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV) \ _(1855, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST) \ - _(1856, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) \ - _(1857, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR) \ + _(1856, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP) \ _(1859, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV) \ _(1860, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST) \ - _(1861, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) \ - _(1862, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR) \ + _(1861, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP) \ _(1864, ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV) \ _(1865, ZEND_FETCH_UNSET_SPEC_CONST_UNUSED) \ - _(1866, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) \ - _(1867, ZEND_FETCH_UNSET_SPEC_TMPVAR_UNUSED) \ + _(1866, ZEND_FETCH_UNSET_SPEC_TMP_UNUSED) \ _(1869, ZEND_FETCH_UNSET_SPEC_CV_UNUSED) \ _(1880, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST) \ - _(1881, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) \ - _(1882, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMPVAR) \ + _(1881, ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP) \ _(1884, ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV) \ _(1890, ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST) \ - _(1891, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) \ - _(1892, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMPVAR) \ + _(1891, ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP) \ _(1894, ZEND_FETCH_DIM_UNSET_SPEC_CV_CV) \ _(1905, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST) \ - _(1906, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) \ - _(1907, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR) \ + _(1906, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP) \ _(1909, ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV) \ _(1910, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST) \ - _(1911, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) \ - _(1912, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR) \ + _(1911, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP) \ _(1914, ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV) \ _(1915, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST) \ - _(1916, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) \ - _(1917, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR) \ + _(1916, ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP) \ _(1919, ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV) \ _(1920, ZEND_FETCH_LIST_R_SPEC_CONST_CONST) \ - _(1921, ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) \ - _(1922, ZEND_FETCH_LIST_R_SPEC_CONST_TMPVAR) \ + _(1921, ZEND_FETCH_LIST_R_SPEC_CONST_TMP) \ _(1924, ZEND_FETCH_LIST_R_SPEC_CONST_CV) \ _(1925, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ - _(1926, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1927, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ + _(1926, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP) \ _(1929, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ _(1930, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ - _(1931, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1932, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ + _(1931, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP) \ _(1934, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ _(1940, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CONST) \ - _(1941, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ - _(1942, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMPVAR) \ + _(1941, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_TMP) \ _(1944, ZEND_FETCH_LIST_R_SPEC_TMPVARCV_CV) \ _(1945, ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST) \ _(1946, ZEND_CHECK_FUNC_ARG_SPEC_UNUSED_CONST) \ @@ -981,17 +773,14 @@ _(1964, ZEND_SEND_VAR_NO_REF_SPEC_VAR_UNUSED) \ _(1966, ZEND_CATCH_SPEC_CONST) \ _(1967, ZEND_THROW_SPEC_CONST) \ - _(1968, ZEND_THROW_SPEC_TMPVAR) \ - _(1969, ZEND_THROW_SPEC_TMPVAR) \ + _(1968, ZEND_THROW_SPEC_TMP) \ _(1971, ZEND_THROW_SPEC_CV) \ _(1972, ZEND_FETCH_CLASS_SPEC_UNUSED_CONST) \ - _(1973, ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) \ - _(1974, ZEND_FETCH_CLASS_SPEC_UNUSED_TMPVAR) \ + _(1973, ZEND_FETCH_CLASS_SPEC_UNUSED_TMP) \ _(1975, ZEND_FETCH_CLASS_SPEC_UNUSED_UNUSED) \ _(1976, ZEND_FETCH_CLASS_SPEC_UNUSED_CV) \ _(1977, ZEND_CLONE_SPEC_CONST) \ - _(1978, ZEND_CLONE_SPEC_TMPVAR) \ - _(1979, ZEND_CLONE_SPEC_TMPVAR) \ + _(1978, ZEND_CLONE_SPEC_TMP) \ _(1980, ZEND_CLONE_SPEC_UNUSED) \ _(1981, ZEND_CLONE_SPEC_CV) \ _(1982, ZEND_RETURN_BY_REF_SPEC_CONST) \ @@ -1003,59 +792,40 @@ _(1990, ZEND_RETURN_BY_REF_SPEC_CV) \ _(1991, ZEND_RETURN_BY_REF_SPEC_OBSERVER) \ _(1992, ZEND_INIT_METHOD_CALL_SPEC_CONST_CONST) \ - _(1993, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(1994, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMPVAR) \ + _(1993, ZEND_INIT_METHOD_CALL_SPEC_CONST_TMP) \ _(1996, ZEND_INIT_METHOD_CALL_SPEC_CONST_CV) \ - _(1997, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST) \ - _(1998, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ - _(1999, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ - _(2001, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) \ - _(2002, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST) \ - _(2003, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ - _(2004, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR) \ - _(2006, ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV) \ + _(1997, ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST) \ + _(1998, ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP) \ + _(2001, ZEND_INIT_METHOD_CALL_SPEC_TMP_CV) \ _(2007, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST) \ - _(2008, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2009, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ + _(2008, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP) \ _(2011, ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV) \ _(2012, ZEND_INIT_METHOD_CALL_SPEC_CV_CONST) \ - _(2013, ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) \ - _(2014, ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR) \ + _(2013, ZEND_INIT_METHOD_CALL_SPEC_CV_TMP) \ _(2016, ZEND_INIT_METHOD_CALL_SPEC_CV_CV) \ _(2017, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST) \ - _(2018, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) \ - _(2019, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR) \ + _(2018, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP) \ _(2020, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_UNUSED) \ _(2021, ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV) \ _(2027, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CONST) \ - _(2028, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) \ - _(2029, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMPVAR) \ + _(2028, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP) \ _(2030, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_UNUSED) \ _(2031, ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_CV) \ _(2032, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CONST) \ - _(2033, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ - _(2034, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMPVAR) \ + _(2033, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_TMP) \ _(2035, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_UNUSED) \ _(2036, ZEND_INIT_STATIC_METHOD_CALL_SPEC_UNUSED_CV) \ _(2042, ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED) \ - _(2043, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) \ - _(2044, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED) \ + _(2043, ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED) \ _(2046, ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED) \ _(2047, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST) \ - _(2048, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) \ - _(2049, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR) \ + _(2048, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP) \ _(2051, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV) \ - _(2052, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) \ - _(2053, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2054, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2056, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) \ - _(2057, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST) \ - _(2058, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2059, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2061, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV) \ + _(2052, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST) \ + _(2053, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP) \ + _(2056, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV) \ _(2067, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST) \ - _(2068, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) \ - _(2069, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR) \ + _(2068, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP) \ _(2071, ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV) \ _(2072, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \ _(2073, ZEND_SEND_VAL_EX_SPEC_CONST_CONST) \ @@ -1070,22 +840,18 @@ _(2142, ZEND_SEND_VAR_SPEC_CV_CONST) \ _(2145, ZEND_SEND_VAR_SPEC_CV_UNUSED) \ _(2147, ZEND_INIT_USER_CALL_SPEC_CONST_CONST) \ - _(2148, ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) \ - _(2149, ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR) \ + _(2148, ZEND_INIT_USER_CALL_SPEC_CONST_TMP) \ _(2151, ZEND_INIT_USER_CALL_SPEC_CONST_CV) \ _(2152, ZEND_SEND_ARRAY_SPEC) \ _(2153, ZEND_SEND_USER_SPEC_CONST) \ _(2154, ZEND_SEND_USER_SPEC_TMP) \ - _(2155, ZEND_SEND_USER_SPEC_VAR) \ _(2157, ZEND_SEND_USER_SPEC_CV) \ _(2158, ZEND_STRLEN_SPEC_CONST) \ - _(2159, ZEND_STRLEN_SPEC_TMPVAR) \ - _(2160, ZEND_STRLEN_SPEC_TMPVAR) \ + _(2159, ZEND_STRLEN_SPEC_TMP) \ _(2162, ZEND_STRLEN_SPEC_CV) \ _(2163, ZEND_DEFINED_SPEC_CONST) \ _(2164, ZEND_TYPE_CHECK_SPEC_CONST) \ - _(2165, ZEND_TYPE_CHECK_SPEC_TMPVAR) \ - _(2166, ZEND_TYPE_CHECK_SPEC_TMPVAR) \ + _(2165, ZEND_TYPE_CHECK_SPEC_TMP) \ _(2168, ZEND_TYPE_CHECK_SPEC_CV) \ _(2169, ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED) \ _(2170, ZEND_VERIFY_RETURN_TYPE_SPEC_TMP_UNUSED) \ @@ -1099,8 +865,7 @@ _(2179, ZEND_FE_FETCH_RW_SPEC_VAR) \ _(2180, ZEND_FE_FREE_SPEC_TMPVAR) \ _(2181, ZEND_INIT_DYNAMIC_CALL_SPEC_CONST) \ - _(2182, ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) \ - _(2183, ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR) \ + _(2182, ZEND_INIT_DYNAMIC_CALL_SPEC_TMP) \ _(2185, ZEND_INIT_DYNAMIC_CALL_SPEC_CV) \ _(2186, ZEND_DO_ICALL_SPEC_RETVAL_UNUSED) \ _(2187, ZEND_DO_ICALL_SPEC_RETVAL_USED) \ @@ -1115,39 +880,29 @@ _(2196, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \ _(2197, ZEND_DO_FCALL_BY_NAME_SPEC_OBSERVER) \ _(2208, ZEND_PRE_INC_OBJ_SPEC_VAR_CONST) \ - _(2209, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2210, ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR) \ + _(2209, ZEND_PRE_INC_OBJ_SPEC_VAR_TMP) \ _(2212, ZEND_PRE_INC_OBJ_SPEC_VAR_CV) \ _(2213, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST) \ - _(2214, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2215, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR) \ + _(2214, ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMP) \ _(2217, ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV) \ _(2218, ZEND_PRE_INC_OBJ_SPEC_CV_CONST) \ - _(2219, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2220, ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR) \ + _(2219, ZEND_PRE_INC_OBJ_SPEC_CV_TMP) \ _(2222, ZEND_PRE_INC_OBJ_SPEC_CV_CV) \ _(2233, ZEND_POST_INC_OBJ_SPEC_VAR_CONST) \ - _(2234, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \ - _(2235, ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR) \ + _(2234, ZEND_POST_INC_OBJ_SPEC_VAR_TMP) \ _(2237, ZEND_POST_INC_OBJ_SPEC_VAR_CV) \ _(2238, ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST) \ - _(2239, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2240, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVAR) \ + _(2239, ZEND_POST_INC_OBJ_SPEC_UNUSED_TMP) \ _(2242, ZEND_POST_INC_OBJ_SPEC_UNUSED_CV) \ _(2243, ZEND_POST_INC_OBJ_SPEC_CV_CONST) \ - _(2244, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \ - _(2245, ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR) \ + _(2244, ZEND_POST_INC_OBJ_SPEC_CV_TMP) \ _(2247, ZEND_POST_INC_OBJ_SPEC_CV_CV) \ _(2248, ZEND_ECHO_SPEC_CONST) \ - _(2249, ZEND_ECHO_SPEC_TMPVAR) \ - _(2250, ZEND_ECHO_SPEC_TMPVAR) \ + _(2249, ZEND_ECHO_SPEC_TMP) \ _(2252, ZEND_ECHO_SPEC_CV) \ - _(2259, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \ - _(2261, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \ - _(2262, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \ - _(2264, ZEND_INSTANCEOF_SPEC_TMPVAR_CONST) \ - _(2266, ZEND_INSTANCEOF_SPEC_TMPVAR_VAR) \ - _(2267, ZEND_INSTANCEOF_SPEC_TMPVAR_UNUSED) \ + _(2259, ZEND_INSTANCEOF_SPEC_TMP_CONST) \ + _(2261, ZEND_INSTANCEOF_SPEC_TMP_VAR) \ + _(2262, ZEND_INSTANCEOF_SPEC_TMP_UNUSED) \ _(2274, ZEND_INSTANCEOF_SPEC_CV_CONST) \ _(2276, ZEND_INSTANCEOF_SPEC_CV_VAR) \ _(2277, ZEND_INSTANCEOF_SPEC_CV_UNUSED) \ @@ -1162,70 +917,54 @@ _(2290, ZEND_DECLARE_ANON_CLASS_SPEC) \ _(2291, ZEND_ADD_ARRAY_UNPACK_SPEC) \ _(2292, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST) \ - _(2293, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \ - _(2294, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR) \ + _(2293, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP) \ _(2296, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV) \ - _(2297, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \ - _(2298, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2299, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2301, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \ - _(2302, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST) \ - _(2303, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2304, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR) \ - _(2306, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV) \ + _(2297, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST) \ + _(2298, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP) \ + _(2301, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV) \ _(2307, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST) \ - _(2308, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \ - _(2309, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR) \ + _(2308, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP) \ _(2311, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV) \ _(2312, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST) \ - _(2313, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \ - _(2314, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR) \ + _(2313, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP) \ _(2316, ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV) \ _(2317, ZEND_HANDLE_EXCEPTION_SPEC) \ _(2318, ZEND_USER_OPCODE_SPEC) \ _(2319, ZEND_ASSERT_CHECK_SPEC) \ _(2320, ZEND_JMP_SET_SPEC_CONST) \ _(2321, ZEND_JMP_SET_SPEC_TMP) \ - _(2322, ZEND_JMP_SET_SPEC_VAR) \ _(2324, ZEND_JMP_SET_SPEC_CV) \ _(2325, ZEND_UNSET_CV_SPEC_CV_UNUSED) \ _(2326, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_SET) \ _(2327, ZEND_ISSET_ISEMPTY_CV_SPEC_CV_UNUSED_EMPTY) \ _(2328, ZEND_FETCH_LIST_W_SPEC_VAR_CONST) \ - _(2329, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \ - _(2330, ZEND_FETCH_LIST_W_SPEC_VAR_TMPVAR) \ + _(2329, ZEND_FETCH_LIST_W_SPEC_VAR_TMP) \ _(2332, ZEND_FETCH_LIST_W_SPEC_VAR_CV) \ _(2333, ZEND_SEPARATE_SPEC_VAR_UNUSED) \ - _(2335, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \ - _(2336, ZEND_FETCH_CLASS_NAME_SPEC_TMPVAR) \ + _(2335, ZEND_FETCH_CLASS_NAME_SPEC_TMP) \ _(2337, ZEND_FETCH_CLASS_NAME_SPEC_UNUSED) \ _(2338, ZEND_FETCH_CLASS_NAME_SPEC_CV) \ _(2339, ZEND_CALL_TRAMPOLINE_SPEC) \ _(2340, ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER) \ _(2341, ZEND_DISCARD_EXCEPTION_SPEC) \ _(2342, ZEND_YIELD_SPEC_CONST_CONST) \ - _(2343, ZEND_YIELD_SPEC_CONST_TMPVAR) \ - _(2344, ZEND_YIELD_SPEC_CONST_TMPVAR) \ + _(2343, ZEND_YIELD_SPEC_CONST_TMP) \ _(2345, ZEND_YIELD_SPEC_CONST_UNUSED) \ _(2346, ZEND_YIELD_SPEC_CONST_CV) \ _(2347, ZEND_YIELD_SPEC_TMP_CONST) \ - _(2348, ZEND_YIELD_SPEC_TMP_TMPVAR) \ - _(2349, ZEND_YIELD_SPEC_TMP_TMPVAR) \ + _(2348, ZEND_YIELD_SPEC_TMP_TMP) \ _(2350, ZEND_YIELD_SPEC_TMP_UNUSED) \ _(2351, ZEND_YIELD_SPEC_TMP_CV) \ _(2352, ZEND_YIELD_SPEC_VAR_CONST) \ - _(2353, ZEND_YIELD_SPEC_VAR_TMPVAR) \ - _(2354, ZEND_YIELD_SPEC_VAR_TMPVAR) \ + _(2353, ZEND_YIELD_SPEC_VAR_TMP) \ _(2355, ZEND_YIELD_SPEC_VAR_UNUSED) \ _(2356, ZEND_YIELD_SPEC_VAR_CV) \ _(2357, ZEND_YIELD_SPEC_UNUSED_CONST) \ - _(2358, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \ - _(2359, ZEND_YIELD_SPEC_UNUSED_TMPVAR) \ + _(2358, ZEND_YIELD_SPEC_UNUSED_TMP) \ _(2360, ZEND_YIELD_SPEC_UNUSED_UNUSED) \ _(2361, ZEND_YIELD_SPEC_UNUSED_CV) \ _(2362, ZEND_YIELD_SPEC_CV_CONST) \ - _(2363, ZEND_YIELD_SPEC_CV_TMPVAR) \ - _(2364, ZEND_YIELD_SPEC_CV_TMPVAR) \ + _(2363, ZEND_YIELD_SPEC_CV_TMP) \ _(2365, ZEND_YIELD_SPEC_CV_UNUSED) \ _(2366, ZEND_YIELD_SPEC_CV_CV) \ _(2367, ZEND_GENERATOR_RETURN_SPEC_CONST) \ @@ -1241,30 +980,21 @@ _(2379, ZEND_RECV_VARIADIC_SPEC_UNUSED) \ _(2380, ZEND_SEND_UNPACK_SPEC) \ _(2381, ZEND_YIELD_FROM_SPEC_CONST) \ - _(2382, ZEND_YIELD_FROM_SPEC_TMPVAR) \ - _(2383, ZEND_YIELD_FROM_SPEC_TMPVAR) \ + _(2382, ZEND_YIELD_FROM_SPEC_TMP) \ _(2385, ZEND_YIELD_FROM_SPEC_CV) \ _(2386, ZEND_COPY_TMP_SPEC_TMPVAR_UNUSED) \ _(2387, ZEND_BIND_GLOBAL_SPEC_CV_CONST) \ _(2388, ZEND_COALESCE_SPEC_CONST) \ _(2389, ZEND_COALESCE_SPEC_TMP) \ - _(2390, ZEND_COALESCE_SPEC_VAR) \ _(2392, ZEND_COALESCE_SPEC_CV) \ _(2393, ZEND_SPACESHIP_SPEC_CONST_CONST) \ - _(2394, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \ - _(2395, ZEND_SPACESHIP_SPEC_CONST_TMPVAR) \ + _(2394, ZEND_SPACESHIP_SPEC_CONST_TMP) \ _(2397, ZEND_SPACESHIP_SPEC_CONST_CV) \ - _(2398, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \ - _(2399, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ - _(2400, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ - _(2402, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \ - _(2403, ZEND_SPACESHIP_SPEC_TMPVAR_CONST) \ - _(2404, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ - _(2405, ZEND_SPACESHIP_SPEC_TMPVAR_TMPVAR) \ - _(2407, ZEND_SPACESHIP_SPEC_TMPVAR_CV) \ + _(2398, ZEND_SPACESHIP_SPEC_TMP_CONST) \ + _(2399, ZEND_SPACESHIP_SPEC_TMP_TMP) \ + _(2402, ZEND_SPACESHIP_SPEC_TMP_CV) \ _(2413, ZEND_SPACESHIP_SPEC_CV_CONST) \ - _(2414, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \ - _(2415, ZEND_SPACESHIP_SPEC_CV_TMPVAR) \ + _(2414, ZEND_SPACESHIP_SPEC_CV_TMP) \ _(2417, ZEND_SPACESHIP_SPEC_CV_CV) \ _(2418, ZEND_FUNC_NUM_ARGS_SPEC_UNUSED_UNUSED) \ _(2419, ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED) \ @@ -1305,576 +1035,559 @@ _(2475, ZEND_SWITCH_STRING_SPEC_TMPVARCV_CONST) \ _(2476, ZEND_IN_ARRAY_SPEC_CONST_CONST) \ _(2477, ZEND_IN_ARRAY_SPEC_TMP_CONST) \ - _(2478, ZEND_IN_ARRAY_SPEC_VAR_CONST) \ _(2480, ZEND_IN_ARRAY_SPEC_CV_CONST) \ _(2481, ZEND_COUNT_SPEC_CONST_UNUSED) \ - _(2482, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \ - _(2483, ZEND_COUNT_SPEC_TMPVAR_UNUSED) \ + _(2482, ZEND_COUNT_SPEC_TMP_UNUSED) \ _(2485, ZEND_COUNT_SPEC_CV_UNUSED) \ _(2486, ZEND_GET_CLASS_SPEC_CONST_UNUSED) \ - _(2487, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \ - _(2488, ZEND_GET_CLASS_SPEC_TMPVAR_UNUSED) \ + _(2487, ZEND_GET_CLASS_SPEC_TMP_UNUSED) \ _(2489, ZEND_GET_CLASS_SPEC_UNUSED_UNUSED) \ _(2490, ZEND_GET_CLASS_SPEC_CV_UNUSED) \ _(2491, ZEND_GET_CALLED_CLASS_SPEC_UNUSED_UNUSED) \ _(2492, ZEND_GET_TYPE_SPEC_CONST_UNUSED) \ _(2493, ZEND_GET_TYPE_SPEC_TMP_UNUSED) \ - _(2494, ZEND_GET_TYPE_SPEC_VAR_UNUSED) \ _(2496, ZEND_GET_TYPE_SPEC_CV_UNUSED) \ _(2497, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CONST) \ - _(2498, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \ - _(2499, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMPVAR) \ + _(2498, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_TMP) \ _(2501, ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CV) \ - _(2502, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \ - _(2503, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ - _(2504, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ - _(2506, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \ - _(2507, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CONST) \ - _(2508, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ - _(2509, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_TMPVAR) \ - _(2511, ZEND_ARRAY_KEY_EXISTS_SPEC_TMPVAR_CV) \ + _(2502, ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CONST) \ + _(2503, ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_TMP) \ + _(2506, ZEND_ARRAY_KEY_EXISTS_SPEC_TMP_CV) \ _(2517, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CONST) \ - _(2518, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \ - _(2519, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMPVAR) \ + _(2518, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_TMP) \ _(2521, ZEND_ARRAY_KEY_EXISTS_SPEC_CV_CV) \ _(2522, ZEND_MATCH_SPEC_CONST_CONST) \ _(2523, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ _(2524, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ _(2526, ZEND_MATCH_SPEC_TMPVARCV_CONST) \ - _(2532, ZEND_CASE_STRICT_SPEC_TMP_CONST) \ - _(2533, ZEND_CASE_STRICT_SPEC_TMP_TMP) \ - _(2534, ZEND_CASE_STRICT_SPEC_TMP_VAR) \ - _(2536, ZEND_CASE_STRICT_SPEC_TMP_CV) \ - _(2537, ZEND_CASE_STRICT_SPEC_VAR_CONST) \ - _(2538, ZEND_CASE_STRICT_SPEC_VAR_TMP) \ - _(2539, ZEND_CASE_STRICT_SPEC_VAR_VAR) \ - _(2541, ZEND_CASE_STRICT_SPEC_VAR_CV) \ - _(2552, ZEND_MATCH_ERROR_SPEC_CONST_UNUSED) \ - _(2553, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ - _(2554, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ - _(2556, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ - _(2557, ZEND_JMP_NULL_SPEC_CONST) \ - _(2558, ZEND_JMP_NULL_SPEC_TMP) \ - _(2559, ZEND_JMP_NULL_SPEC_VAR) \ - _(2561, ZEND_JMP_NULL_SPEC_CV) \ - _(2562, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED) \ - _(2563, ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED) \ - _(2564, ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED) \ - _(2565, ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED) \ - _(2566, ZEND_BIND_INIT_STATIC_OR_JMP_SPEC_CV) \ - _(2567, ZEND_FRAMELESS_ICALL_0_SPEC_UNUSED_UNUSED) \ - _(2568, ZEND_FRAMELESS_ICALL_0_SPEC_OBSERVER) \ - _(2569, ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED) \ - _(2570, ZEND_FRAMELESS_ICALL_1_SPEC_OBSERVER) \ - _(2571, ZEND_FRAMELESS_ICALL_2_SPEC) \ - _(2572, ZEND_FRAMELESS_ICALL_2_SPEC_OBSERVER) \ - _(2573, ZEND_FRAMELESS_ICALL_3_SPEC) \ - _(2574, ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER) \ - _(2575, ZEND_JMP_FRAMELESS_SPEC_CONST) \ - _(2576, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED) \ - _(2577, ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST) \ - _(2578, ZEND_INIT_FCALL_OFFSET_SPEC_CONST) \ - _(2579, ZEND_RECV_NOTYPE_SPEC) \ - _(2581, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \ - _(2582, ZEND_COUNT_ARRAY_SPEC_TMPVAR_UNUSED) \ - _(2584, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED) \ - _(2585, ZEND_JMP_FORWARD_SPEC) \ - _(2591, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2592, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2593, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2595, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2596, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2597, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2598, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2600, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2606, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2607, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2608, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2610, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2616, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ - _(2617, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2618, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2620, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2621, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ - _(2622, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2623, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2625, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2631, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ - _(2632, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2633, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2635, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2641, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2642, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2643, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2645, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2646, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2647, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2648, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2650, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2656, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2657, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2658, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2660, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2662, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2663, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2665, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2666, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2667, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2668, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2670, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2671, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2672, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2673, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2675, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2681, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2682, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2683, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2685, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2687, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2688, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2690, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2691, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ - _(2692, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2693, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2695, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2696, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ - _(2697, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2698, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2700, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2706, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ - _(2707, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2708, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2710, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2712, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2713, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2715, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2716, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2717, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2718, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2720, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2721, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2722, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2723, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2725, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2731, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2732, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2733, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2735, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2741, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2742, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2743, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2745, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2746, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2747, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2748, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2750, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2756, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ - _(2757, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2758, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2760, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2766, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ - _(2767, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2768, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2770, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2771, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ - _(2772, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2773, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2775, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2781, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ - _(2782, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2783, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2785, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2791, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2792, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2793, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2795, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2796, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2797, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2798, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2800, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2806, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2807, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2808, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2810, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2826, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2827, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2828, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2829, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2830, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2831, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2832, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2833, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2834, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2838, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2839, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2840, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2841, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2842, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2843, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2844, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2845, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2846, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2847, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2848, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2849, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2853, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2854, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2855, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2871, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2872, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2873, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2874, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2875, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2876, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2877, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2878, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2879, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2883, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2884, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2885, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2901, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2902, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2903, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2904, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2905, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2906, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2907, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2908, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2909, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2913, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2914, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2915, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2916, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2917, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2918, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2919, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2920, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2921, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2922, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2923, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2924, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2928, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2929, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2930, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2946, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2947, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2948, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2949, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2950, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2951, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2952, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2953, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2954, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2958, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2959, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2960, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2976, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2977, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2978, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2979, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2980, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2981, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2982, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2983, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2984, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2988, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2989, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2990, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2991, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2992, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2993, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2994, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2995, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2996, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2997, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2998, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2999, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3003, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3004, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3005, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3021, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3022, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3023, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3024, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3025, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3026, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3027, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3028, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3029, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3033, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3034, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3035, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3051, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3052, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3053, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3054, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3055, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3056, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3057, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3058, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3059, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3063, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3064, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3065, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3066, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3067, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3068, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3069, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3070, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3071, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3072, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3073, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3074, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3078, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3079, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3080, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3096, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3097, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3098, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3099, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3100, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3101, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3102, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3103, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3104, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3108, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3109, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3110, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3111, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST) \ - _(3112, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3113, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3114, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST) \ - _(3115, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3116, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3117, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3121, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3122, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3126, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3130, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3131, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3132, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3133, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3134, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3135, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3139, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3140, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3141, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3144, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3145, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3146, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3147, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3148, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3149, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3154, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3155, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3156, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3157, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3158, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3159, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3160, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3161, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3162, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3163, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3164, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3165, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3169, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3170, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3171, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3187, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3188, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3189, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3190, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3191, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3192, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3193, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3194, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3195, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3199, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3200, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3201, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3205, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3206, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3207, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3208, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3209, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3210, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3214, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3215, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3216, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3219, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3220, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3221, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3222, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3223, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3224, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3229, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3230, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3231, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3232, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3233, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3234, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3235, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3236, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3237, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3238, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3239, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3240, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3244, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3245, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3246, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3262, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3263, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3264, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3265, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3266, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3267, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3268, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3269, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3270, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3274, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3275, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3276, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3280, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3281, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3282, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3283, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3284, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3285, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3289, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3290, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3291, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3294, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3295, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3296, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3297, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3298, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3299, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3304, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3305, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3306, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3307, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3308, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3309, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3310, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3311, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3312, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3313, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3314, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3315, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3319, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3320, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3321, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3337, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3338, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3339, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3340, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3341, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3342, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3343, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3344, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3345, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3349, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3350, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3351, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3355, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3356, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3357, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3358, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3359, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3360, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3364, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3365, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3366, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3369, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3370, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3371, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3372, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3373, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3374, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3379, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3380, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3381, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3382, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3383, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3384, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3385, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3386, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3387, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3388, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3389, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3390, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3394, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3395, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3396, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3412, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3413, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3414, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3415, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3416, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3417, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3418, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3419, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3420, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3424, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3425, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3426, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3427, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3428, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3429, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3430, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ - _(3431, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3432, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3433, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3434, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ - _(3435, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3436, ZEND_POST_INC_LONG_SPEC_CV) \ - _(3437, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3438, ZEND_POST_DEC_LONG_SPEC_CV) \ - _(3439, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ - _(3440, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3441, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3443, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3444, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ - _(3445, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3446, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3448, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3449, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ - _(3450, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3451, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3453, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3455, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3456, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3458, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3459, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ - _(3460, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3461, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3463, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3464, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ - _(3465, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3466, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3468, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3474, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ - _(3475, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3476, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3478, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3481, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ - _(3483, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ - _(3486, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ - _(3488, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ - _(3489, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ - _(3490, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ - _(3491, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ - _(3492, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ - _(3492+1, ZEND_NULL) + _(2527, ZEND_CASE_STRICT_SPEC_TMP_CONST) \ + _(2528, ZEND_CASE_STRICT_SPEC_TMP_TMP) \ + _(2531, ZEND_CASE_STRICT_SPEC_TMP_CV) \ + _(2532, ZEND_MATCH_ERROR_SPEC_CONST_UNUSED) \ + _(2533, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ + _(2534, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ + _(2536, ZEND_MATCH_ERROR_SPEC_TMPVARCV_UNUSED) \ + _(2537, ZEND_JMP_NULL_SPEC_CONST) \ + _(2538, ZEND_JMP_NULL_SPEC_TMP) \ + _(2541, ZEND_JMP_NULL_SPEC_CV) \ + _(2542, ZEND_CHECK_UNDEF_ARGS_SPEC_UNUSED_UNUSED) \ + _(2543, ZEND_FETCH_GLOBALS_SPEC_UNUSED_UNUSED) \ + _(2544, ZEND_VERIFY_NEVER_TYPE_SPEC_UNUSED_UNUSED) \ + _(2545, ZEND_CALLABLE_CONVERT_SPEC_UNUSED_UNUSED) \ + _(2546, ZEND_BIND_INIT_STATIC_OR_JMP_SPEC_CV) \ + _(2547, ZEND_FRAMELESS_ICALL_0_SPEC_UNUSED_UNUSED) \ + _(2548, ZEND_FRAMELESS_ICALL_0_SPEC_OBSERVER) \ + _(2549, ZEND_FRAMELESS_ICALL_1_SPEC_UNUSED) \ + _(2550, ZEND_FRAMELESS_ICALL_1_SPEC_OBSERVER) \ + _(2551, ZEND_FRAMELESS_ICALL_2_SPEC) \ + _(2552, ZEND_FRAMELESS_ICALL_2_SPEC_OBSERVER) \ + _(2553, ZEND_FRAMELESS_ICALL_3_SPEC) \ + _(2554, ZEND_FRAMELESS_ICALL_3_SPEC_OBSERVER) \ + _(2555, ZEND_JMP_FRAMELESS_SPEC_CONST) \ + _(2556, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED) \ + _(2557, ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST) \ + _(2558, ZEND_DEREF_SPEC_VAR_UNUSED) \ + _(2559, ZEND_INIT_FCALL_OFFSET_SPEC_CONST) \ + _(2560, ZEND_RECV_NOTYPE_SPEC) \ + _(2562, ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED) \ + _(2565, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED) \ + _(2566, ZEND_JMP_FORWARD_SPEC) \ + _(2572, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2573, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2574, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2576, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2577, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2578, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2579, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2581, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2587, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2588, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2589, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2591, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2597, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2598, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2599, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2601, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2602, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2603, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2604, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2606, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2612, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2613, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2614, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2616, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2622, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2623, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2624, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2626, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2627, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2628, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2629, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2631, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2637, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2638, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2639, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2641, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2643, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2644, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2646, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2647, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2648, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2649, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2651, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2652, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2653, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2654, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2656, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2662, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2663, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2664, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2666, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2668, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2669, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2671, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2672, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2673, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2674, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2676, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2677, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2678, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2679, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2681, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2687, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2688, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2689, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2691, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2693, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2694, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2696, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2697, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2698, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2699, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2701, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2702, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2703, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2704, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2706, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2712, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2713, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2714, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2716, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2722, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2723, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2724, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2726, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2727, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2728, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2729, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2731, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2737, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2738, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2739, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2741, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2747, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2748, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2749, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2751, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2752, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2753, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2754, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2756, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2762, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2763, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2764, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2766, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2772, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2773, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2774, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2776, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2777, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2778, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2779, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2781, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2787, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2788, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2789, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2791, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2807, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2808, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2809, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2810, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2811, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2812, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2813, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2814, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2815, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2819, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2820, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2821, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2822, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2823, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2824, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2825, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2826, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2827, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2828, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2829, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2830, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2834, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2835, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2836, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2852, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2853, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2854, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2855, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2856, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2857, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2858, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2859, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2860, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2864, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2865, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2866, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2882, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2883, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2884, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2885, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2886, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2887, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2888, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2889, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2890, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2894, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2895, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2896, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2897, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2898, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2899, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2900, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2901, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2902, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2903, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2904, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2905, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2909, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2910, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2911, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2927, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2928, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2929, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2930, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2931, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2932, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2933, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2934, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2935, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2939, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2940, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2941, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2957, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2958, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2959, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2960, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2961, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2962, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2963, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2964, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2965, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2969, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2970, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2971, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2972, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2973, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2974, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2975, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2976, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2977, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2978, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2979, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2980, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2984, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2985, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2986, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3002, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3003, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3004, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3005, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3006, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3007, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3008, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3009, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3010, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3014, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3015, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3016, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3032, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3033, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3034, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3035, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3036, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3037, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3038, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3039, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3040, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3044, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3045, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3046, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3047, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3048, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3049, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3050, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3051, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3052, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3053, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3054, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3055, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3059, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3060, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3061, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3077, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3078, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3079, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3080, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3081, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3082, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3083, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3084, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3085, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3089, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3090, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3091, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3092, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST) \ + _(3093, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3094, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3095, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST) \ + _(3096, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3097, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3098, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3102, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3103, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3107, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3111, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3112, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3113, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3114, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3115, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3116, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3120, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3121, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3122, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3123, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3124, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3125, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3126, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3127, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3128, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3129, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3130, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3131, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3135, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3136, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3137, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3138, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3139, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3140, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3141, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3144, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3145, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3146, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3151, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3152, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3168, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3169, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3170, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3171, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3172, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3173, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3174, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3175, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3176, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3180, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3181, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3182, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3186, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3187, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3188, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3189, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3190, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3191, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3195, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3196, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3197, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3198, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3199, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3200, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3201, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3202, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3203, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3204, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3205, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3206, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3210, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3211, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3212, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3213, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3214, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3215, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3216, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3219, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3220, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3221, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3226, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3227, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3243, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3244, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3245, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3246, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3247, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3248, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3249, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3250, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3251, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3255, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3256, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3257, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3261, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3262, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3263, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3264, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3265, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3266, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3270, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3271, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3272, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3273, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3274, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3276, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3277, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3278, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3279, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3280, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3281, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3285, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3286, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3287, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3288, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3289, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3290, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3291, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3294, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3295, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3296, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3301, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3302, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3318, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3319, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3320, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3321, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3322, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3323, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3324, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3325, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3326, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3330, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3331, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3332, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3336, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3337, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3338, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3339, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3340, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3341, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3345, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3346, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3347, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3348, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3349, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3351, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3352, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3353, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3354, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3355, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3356, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3360, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3361, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3362, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3363, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3364, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3365, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3366, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3369, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3370, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3371, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3376, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3377, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3393, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3394, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3395, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3396, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3397, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3398, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3399, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3400, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3401, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3405, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3406, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3407, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3408, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3409, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3410, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3411, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ + _(3412, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3413, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3414, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3415, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ + _(3416, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3417, ZEND_POST_INC_LONG_SPEC_CV) \ + _(3418, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3419, ZEND_POST_DEC_LONG_SPEC_CV) \ + _(3420, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ + _(3421, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3422, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3424, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3425, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ + _(3426, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3427, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3429, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3430, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ + _(3431, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3432, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3434, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3436, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3437, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3439, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3440, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3441, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3442, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3444, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3445, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3446, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3447, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3449, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3455, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ + _(3456, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3457, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3459, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3462, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ + _(3464, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ + _(3467, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ + _(3469, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ + _(3470, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ + _(3471, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ + _(3472, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ + _(3473, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ + _(3473+1, ZEND_NULL) diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 936a96e55e41f..944f359a7b268 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -22,7 +22,7 @@ #include #include -static const char *zend_vm_opcodes_names[211] = { +static const char *zend_vm_opcodes_names[212] = { "ZEND_NOP", "ZEND_ADD", "ZEND_SUB", @@ -234,42 +234,43 @@ static const char *zend_vm_opcodes_names[211] = { "ZEND_JMP_FRAMELESS", "ZEND_INIT_PARENT_PROPERTY_HOOK_CALL", "ZEND_DECLARE_ATTRIBUTED_CONST", + "ZEND_DEREF", }; -static uint32_t zend_vm_opcodes_flags[211] = { +static uint32_t zend_vm_opcodes_flags[212] = { 0x00000000, 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, @@ -280,20 +281,20 @@ static uint32_t zend_vm_opcodes_flags[211] = { 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, @@ -308,34 +309,34 @@ static uint32_t zend_vm_opcodes_flags[211] = { 0x0100a173, 0x01040300, 0x00000005, - 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, @@ -345,37 +346,37 @@ static uint32_t zend_vm_opcodes_flags[211] = { 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, 0x00000005, - 0x01000700, + 0x01000300, 0x00000000, 0x00000000, 0x00000000, - 0x00040751, - 0x00040751, - 0x00040751, - 0x00040751, - 0x00000007, + 0x00040351, + 0x00040351, + 0x00040351, + 0x00040351, + 0x00000003, 0x00000000, - 0x00047305, + 0x00047301, 0x00000000, 0x00000101, 0x00001000, @@ -385,29 +386,29 @@ static uint32_t zend_vm_opcodes_flags[211] = { 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, @@ -427,11 +428,11 @@ static uint32_t zend_vm_opcodes_flags[211] = { 0x0300030b, 0x0300030b, 0x01000303, - 0x00000107, - 0x00000107, + 0x00000103, + 0x00000103, 0x00000101, 0x00000103, - 0x00000707, + 0x00000303, 0x0300030b, 0x00000301, 0x0000010b, @@ -448,6 +449,7 @@ static uint32_t zend_vm_opcodes_flags[211] = { 0x01042003, 0x01001103, 0x00000303, + 0x00000101, }; ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(uint8_t opcode) { diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 287dec375f3a9..f1a1eb8b6dc94 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -330,7 +330,8 @@ END_EXTERN_C() #define ZEND_JMP_FRAMELESS 208 #define ZEND_INIT_PARENT_PROPERTY_HOOK_CALL 209 #define ZEND_DECLARE_ATTRIBUTED_CONST 210 +#define ZEND_DEREF 211 -#define ZEND_VM_LAST_OPCODE 210 +#define ZEND_VM_LAST_OPCODE 211 #endif diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 1c5cab899e783..0bcf972447a93 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -10078,7 +10078,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen } bool may_have_extra_named_params = - opline->extended_value == ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS && + (opline->extended_value & ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS) && (!func || func->common.fn_flags & ZEND_ACC_VARIADIC); if (!jit->reuse_ip) { diff --git a/ext/opcache/tests/dump_property_hooks.phpt b/ext/opcache/tests/dump_property_hooks.phpt index 5083ad385f31f..3073ca89ff985 100644 --- a/ext/opcache/tests/dump_property_hooks.phpt +++ b/ext/opcache/tests/dump_property_hooks.phpt @@ -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 diff --git a/ext/opcache/tests/match/001.phpt b/ext/opcache/tests/match/001.phpt index 502400681cf12..8dcad03c45e32 100644 --- a/ext/opcache/tests/match/001.phpt +++ b/ext/opcache/tests/match/001.phpt @@ -34,9 +34,9 @@ $_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 @@ -44,7 +44,7 @@ $_main: 0010 SEND_VAR V2 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) diff --git a/ext/opcache/tests/match/003.phpt b/ext/opcache/tests/match/003.phpt index 24f3cd2612105..12c6bbf99b850 100644 --- a/ext/opcache/tests/match/003.phpt +++ b/ext/opcache/tests/match/003.phpt @@ -35,9 +35,9 @@ $_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 @@ -45,7 +45,7 @@ $_main: 0010 SEND_VAR V2 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) diff --git a/ext/opcache/tests/match/004.phpt b/ext/opcache/tests/match/004.phpt index d9d4149b94510..f9fe03cf9f143 100644 --- a/ext/opcache/tests/match/004.phpt +++ b/ext/opcache/tests/match/004.phpt @@ -40,9 +40,9 @@ $_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 @@ -57,7 +57,7 @@ $_main: 0017 SEND_VAR V2 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) diff --git a/ext/opcache/tests/named_parameter_new.phpt b/ext/opcache/tests/named_parameter_new.phpt index 1f6f64333c988..f8979766421c6 100644 --- a/ext/opcache/tests/named_parameter_new.phpt +++ b/ext/opcache/tests/named_parameter_new.phpt @@ -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) diff --git a/ext/opcache/tests/nodiscard_001.phpt b/ext/opcache/tests/nodiscard_001.phpt index 7e232f8f44e41..8f87e7877bcfd 100644 --- a/ext/opcache/tests/nodiscard_001.phpt +++ b/ext/opcache/tests/nodiscard_001.phpt @@ -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) diff --git a/ext/opcache/tests/opt/block_pass_007.phpt b/ext/opcache/tests/opt/block_pass_007.phpt index b2dca320d9b76..1afecfc3e171d 100644 --- a/ext/opcache/tests/opt/block_pass_007.phpt +++ b/ext/opcache/tests/opt/block_pass_007.phpt @@ -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 diff --git a/ext/opcache/tests/opt/dce_006.phpt b/ext/opcache/tests/opt/dce_006.phpt index 2596651ed3e91..2c1fe749ae980 100644 --- a/ext/opcache/tests/opt/dce_006.phpt +++ b/ext/opcache/tests/opt/dce_006.phpt @@ -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 diff --git a/ext/opcache/tests/opt/gh11170.phpt b/ext/opcache/tests/opt/gh11170.phpt index 9ea733f92b104..ae26cb4081f46 100644 --- a/ext/opcache/tests/opt/gh11170.phpt +++ b/ext/opcache/tests/opt/gh11170.phpt @@ -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: diff --git a/ext/opcache/tests/opt/gh18107_1.phpt b/ext/opcache/tests/opt/gh18107_1.phpt index 062ccd464559b..a2cf3162090c3 100644 --- a/ext/opcache/tests/opt/gh18107_1.phpt +++ b/ext/opcache/tests/opt/gh18107_1.phpt @@ -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 diff --git a/ext/opcache/tests/opt/gh18107_2.phpt b/ext/opcache/tests/opt/gh18107_2.phpt index bd34a54edf6e6..74a709223e5a6 100644 --- a/ext/opcache/tests/opt/gh18107_2.phpt +++ b/ext/opcache/tests/opt/gh18107_2.phpt @@ -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: diff --git a/ext/opcache/tests/opt/jmp_001.phpt b/ext/opcache/tests/opt/jmp_001.phpt index 71ff73671e81b..d5491dfe1ab40 100644 --- a/ext/opcache/tests/opt/jmp_001.phpt +++ b/ext/opcache/tests/opt/jmp_001.phpt @@ -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) diff --git a/ext/opcache/tests/opt/sccp_022.phpt b/ext/opcache/tests/opt/sccp_022.phpt index ffcc48b0dccd9..27d7b6d719287 100644 --- a/ext/opcache/tests/opt/sccp_022.phpt +++ b/ext/opcache/tests/opt/sccp_022.phpt @@ -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) diff --git a/ext/opcache/tests/opt/sccp_032.phpt b/ext/opcache/tests/opt/sccp_032.phpt index 6ee4a837ecd37..73ccb26654705 100644 --- a/ext/opcache/tests/opt/sccp_032.phpt +++ b/ext/opcache/tests/opt/sccp_032.phpt @@ -30,27 +30,27 @@ $_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=5, 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 +0001 YIELD_FROM array(...) +0002 YIELD null +0003 YIELD_FROM array(...) 0004 GENERATOR_RETURN null NULL 3 diff --git a/ext/opcache/tests/opt/type_inference_final_class.phpt b/ext/opcache/tests/opt/type_inference_final_class.phpt index 3c4aa03d8cb4e..be3b584b3c61e 100644 --- a/ext/opcache/tests/opt/type_inference_final_class.phpt +++ b/ext/opcache/tests/opt/type_inference_final_class.phpt @@ -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 diff --git a/ext/opcache/tests/pipe_optimizations.phpt b/ext/opcache/tests/pipe_optimizations.phpt index 5a8750845ddc8..5115eaff59a24 100644 --- a/ext/opcache/tests/pipe_optimizations.phpt +++ b/ext/opcache/tests/pipe_optimizations.phpt @@ -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) diff --git a/sapi/phpdbg/tests/print_001.phpt b/sapi/phpdbg/tests/print_001.phpt index ae1b7991973bd..91e8b936fd315 100644 --- a/sapi/phpdbg/tests/print_001.phpt +++ b/sapi/phpdbg/tests/print_001.phpt @@ -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") diff --git a/sapi/phpdbg/tests/watch_005.phpt b/sapi/phpdbg/tests/watch_005.phpt index aacc158f61740..a831db464eb61 100644 --- a/sapi/phpdbg/tests/watch_005.phpt +++ b/sapi/phpdbg/tests/watch_005.phpt @@ -35,9 +35,9 @@ New value: aa prompt> [Breaking on watchpoint $a] Old value inaccessible or destroyed New value (reference): aa ->00006: $a[1] = "b"; +>00005: $c = &$a; + 00006: $a[1] = "b"; 00007: - 00008: exit; prompt> [Breaking on watchpoint $a] Old value: aa New value: ab From f8b7219c4f028e105725115ac0a6fa2fa7362132 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Mon, 1 Dec 2025 16:32:51 +0100 Subject: [PATCH 02/19] Revert now unchanged test --- sapi/phpdbg/tests/watch_005.phpt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sapi/phpdbg/tests/watch_005.phpt b/sapi/phpdbg/tests/watch_005.phpt index a831db464eb61..aacc158f61740 100644 --- a/sapi/phpdbg/tests/watch_005.phpt +++ b/sapi/phpdbg/tests/watch_005.phpt @@ -35,9 +35,9 @@ New value: aa prompt> [Breaking on watchpoint $a] Old value inaccessible or destroyed New value (reference): aa ->00005: $c = &$a; - 00006: $a[1] = "b"; +>00006: $a[1] = "b"; 00007: + 00008: exit; prompt> [Breaking on watchpoint $a] Old value: aa New value: ab From 5710a4aba3c6067cea28b71f12eb705a5c38b43a Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 2 Dec 2025 18:45:25 +0100 Subject: [PATCH 03/19] Avoid FREE for INCLUDE_OR_EVAL --- Zend/zend_compile.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index e75a3d878fb31..91018b68f01da 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -799,6 +799,7 @@ static void zend_do_free(znode *op1) /* {{{ */ case ZEND_DO_FCALL_BY_NAME: case ZEND_YIELD: case ZEND_YIELD_FROM: + case ZEND_INCLUDE_OR_EVAL: SET_UNUSED(opline->result); return; } From 9bdeafe20c6499fcf0ea4b727c52ed7f3c7c151c Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 2 Dec 2025 19:16:07 +0100 Subject: [PATCH 04/19] Fix eliding of call result in optimizer --- Zend/Optimizer/block_pass.c | 20 +++---------- Zend/zend_compile.c | 59 ++++++++++++++++++++++--------------- Zend/zend_compile.h | 2 ++ 3 files changed, 42 insertions(+), 39 deletions(-) diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index b1fd8e44222e5..d8a925e689e9f 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -289,20 +289,10 @@ 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: + default: + if (!zend_op_may_elide_result(src->opcode)) { + break; + } if (src < op_array->opcodes + block->start) { break; } @@ -311,8 +301,6 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array MAKE_NOP(opline); ++(*opt_count); break; - default: - break; } } } else if (opline->op1_type == IS_VAR) { diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 91018b68f01da..d142772fa3b8f 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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,29 +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: - 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: - SET_UNUSED(opline->result); - return; + default: + if (zend_op_may_elide_result(opline->opcode)) { + SET_UNUSED(opline->result); + return; + } + break; } } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 86fab4b57ded6..05bdcb20da8f5 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -1326,4 +1326,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 */ From e38a22d352ae3a8e3cdeaea4dc68a7f00f4c1f63 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 2 Dec 2025 20:00:57 +0100 Subject: [PATCH 05/19] Compile calls with R in known by-value arg position --- Zend/zend_compile.c | 4 +++- ext/opcache/tests/match/001.phpt | 4 ++-- ext/opcache/tests/match/003.phpt | 4 ++-- ext/opcache/tests/match/004.phpt | 8 ++++---- ext/opcache/tests/opt/gh14873.phpt | 28 ++++++++++++++-------------- sapi/phpdbg/tests/print_001.phpt | 4 ++-- sapi/phpdbg/tests/print_002.phpt | 4 ++-- 7 files changed, 29 insertions(+), 27 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index d142772fa3b8f..840c2ee9af6d2 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3846,7 +3846,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, is_globals_fetch(arg) ? BP_VAR_R : BP_VAR_FUNC_ARG, false); + uint32_t type = is_globals_fetch(arg) || (fbc && !ARG_MUST_BE_SENT_BY_REF(fbc, arg_num) && !ARG_MAY_BE_SENT_BY_REF(fbc, arg_num)) + ? BP_VAR_R : BP_VAR_FUNC_ARG; + zend_compile_var(&arg_node, arg, type, 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)) { diff --git a/ext/opcache/tests/match/001.phpt b/ext/opcache/tests/match/001.phpt index 8dcad03c45e32..9d9ad2ac9e321 100644 --- a/ext/opcache/tests/match/001.phpt +++ b/ext/opcache/tests/match/001.phpt @@ -40,8 +40,8 @@ $_main: 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 T1 diff --git a/ext/opcache/tests/match/003.phpt b/ext/opcache/tests/match/003.phpt index 12c6bbf99b850..8bed847178839 100644 --- a/ext/opcache/tests/match/003.phpt +++ b/ext/opcache/tests/match/003.phpt @@ -41,8 +41,8 @@ $_main: 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 T1 diff --git a/ext/opcache/tests/match/004.phpt b/ext/opcache/tests/match/004.phpt index f9fe03cf9f143..ae7b40f20f587 100644 --- a/ext/opcache/tests/match/004.phpt +++ b/ext/opcache/tests/match/004.phpt @@ -46,15 +46,15 @@ $_main: 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 T1 diff --git a/ext/opcache/tests/opt/gh14873.phpt b/ext/opcache/tests/opt/gh14873.phpt index d442128d023c8..20428b5bcd2b3 100644 --- a/ext/opcache/tests/opt/gh14873.phpt +++ b/ext/opcache/tests/opt/gh14873.phpt @@ -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) diff --git a/sapi/phpdbg/tests/print_001.phpt b/sapi/phpdbg/tests/print_001.phpt index 91e8b936fd315..031b4d5a961b9 100644 --- a/sapi/phpdbg/tests/print_001.phpt +++ b/sapi/phpdbg/tests/print_001.phpt @@ -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)] diff --git a/sapi/phpdbg/tests/print_002.phpt b/sapi/phpdbg/tests/print_002.phpt index 3b46fe0c13c72..a183939cad3d6 100644 --- a/sapi/phpdbg/tests/print_002.phpt +++ b/sapi/phpdbg/tests/print_002.phpt @@ -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") From dba22940eb9c8854c7958d1e1c493e56ed060e5d Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 2 Dec 2025 21:51:57 +0100 Subject: [PATCH 06/19] ZEND_DEREF can't throw, and doesn't have side-effects --- Zend/Optimizer/dce.c | 1 + Zend/Optimizer/zend_inference.c | 1 + 2 files changed, 2 insertions(+) diff --git a/Zend/Optimizer/dce.c b/Zend/Optimizer/dce.c index 41fd0f6c30af4..c550cb24bbe5d 100644 --- a/Zend/Optimizer/dce.c +++ b/Zend/Optimizer/dce.c @@ -125,6 +125,7 @@ static inline bool may_have_side_effects( case ZEND_FUNC_GET_ARGS: case ZEND_ARRAY_KEY_EXISTS: case ZEND_COPY_TMP: + case ZEND_DEREF: /* No side effects */ return false; case ZEND_FREE: diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index 54670c804d006..147242a5fa98f 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -5033,6 +5033,7 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op case ZEND_COPY_TMP: case ZEND_JMP_NULL: case ZEND_JMP_FRAMELESS: + case ZEND_DEREF: return 0; case ZEND_IS_IDENTICAL: case ZEND_IS_NOT_IDENTICAL: From 143dfe8f9280dd3a58cabc9aa57bdd57a2081da7 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 2 Dec 2025 22:58:15 +0100 Subject: [PATCH 07/19] Support FREE dce with T = QM_ASSIGN src --- Zend/Optimizer/block_pass.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index d8a925e689e9f..af2323afebdee 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -289,6 +289,17 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array MAKE_NOP(opline); ++(*opt_count); break; + case ZEND_QM_ASSIGN: + src->result_type = IS_UNUSED; + VAR_SOURCE(opline->op1) = NULL; + MAKE_NOP(opline); + ++(*opt_count); + if (src->op1_type & (IS_VAR|IS_TMP_VAR)) { + src->opcode = ZEND_FREE; + } else { + MAKE_NOP(src); + } + break; default: if (!zend_op_may_elide_result(src->opcode)) { break; From 6320984d9d763b6a3d7069a775c8a5f31dc2e0a1 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 2 Dec 2025 23:07:05 +0100 Subject: [PATCH 08/19] Elide ZEND_DEREF for by-ref list assign in stmt context --- Zend/zend_compile.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 840c2ee9af6d2..689ae6e29b52d 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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); #ifdef ZEND_CHECK_STACK_LIMIT zend_never_inline static void zend_stack_limit_error(void) @@ -3406,8 +3406,7 @@ static void zend_compile_list_assign( } if (result) { - if ((type == BP_VAR_R || type == BP_VAR_IS) && expr_node->op_type == IS_VAR) { - // FIXME: [&$a] = ...; currently emits ZEND_DEREF, avoidable? + if ((type == BP_VAR_R || type == BP_VAR_IS) && expr_node->op_type == IS_VAR) { zend_emit_op_tmp(result, ZEND_DEREF, expr_node, NULL); } else { *result = *expr_node; @@ -3482,7 +3481,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) /* {{{ */ { zend_ast *var_ast = ast->child[0]; zend_ast *expr_ast = ast->child[1]; @@ -3572,7 +3571,10 @@ static void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */ } } - zend_compile_list_assign(result, var_ast, &expr_node, var_ast->attr, BP_VAR_R); + zend_compile_list_assign(!stmt ? result : NULL, var_ast, &expr_node, var_ast->attr, BP_VAR_R); + if (stmt) { + result->op_type = IS_UNUSED; + } return; EMPTY_SWITCH_DEFAULT_CASE(); } @@ -11958,6 +11960,12 @@ 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, true); + zend_do_free(&result); + return; + } case ZEND_AST_ASSIGN_REF: zend_compile_assign_ref(NULL, ast, BP_VAR_R); return; @@ -12007,7 +12015,7 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */ zend_compile_var(result, ast, BP_VAR_R, false); return; case ZEND_AST_ASSIGN: - zend_compile_assign(result, ast); + zend_compile_assign(result, ast, false); return; case ZEND_AST_ASSIGN_REF: zend_compile_assign_ref(result, ast, BP_VAR_R); From 9ad830ac1917b6b62ab99033c8844d3018cffd28 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 2 Dec 2025 23:16:46 +0100 Subject: [PATCH 09/19] Fix QM_ASSIGN optimization --- Zend/Optimizer/block_pass.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index af2323afebdee..058d1d0f7304a 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -290,6 +290,9 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array ++(*opt_count); break; case ZEND_QM_ASSIGN: + if (src < op_array->opcodes + block->start) { + break; + } src->result_type = IS_UNUSED; VAR_SOURCE(opline->op1) = NULL; MAKE_NOP(opline); From ce6188697a7454346adc71fc07ce0789f69013de Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 2 Dec 2025 23:21:14 +0100 Subject: [PATCH 10/19] Re-enable optimization Works now, for some reason --- Zend/zend_compile.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 689ae6e29b52d..27a6b1b585e01 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -4370,7 +4370,6 @@ static zend_result zend_compile_func_cufa(znode *result, zend_ast_list *args, ze bool is_fully_qualified; zend_string *name = zend_resolve_function_name(orig_name, args->child[1]->child[0]->attr, &is_fully_qualified); -#if 0 zend_ast_list *list = zend_ast_get_list(args->child[1]->child[1]); if (zend_string_equals_literal_ci(name, "array_slice") && !zend_args_contain_unpack_or_named(list) @@ -4393,7 +4392,6 @@ static zend_result zend_compile_func_cufa(znode *result, zend_ast_list *args, ze return SUCCESS; } } -#endif zend_string_release_ex(name, 0); } zend_compile_expr(&arg_node, args->child[1]); From 9ddff663eec3b4a0b845142e1894ce203ac49b18 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 2 Dec 2025 23:39:31 +0100 Subject: [PATCH 11/19] Fix YIELD_FROM dce without result --- Zend/Optimizer/dce.c | 8 +++++++- Zend/Optimizer/zend_inference.c | 7 +++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Zend/Optimizer/dce.c b/Zend/Optimizer/dce.c index c550cb24bbe5d..14d014bc9e3c8 100644 --- a/Zend/Optimizer/dce.c +++ b/Zend/Optimizer/dce.c @@ -163,10 +163,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: diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index 147242a5fa98f..e5b6576944e5a 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -5337,6 +5337,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; } From a4fa5518ced2a6394a9785603dcefcdf82692d15 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Wed, 3 Dec 2025 00:09:42 +0100 Subject: [PATCH 12/19] Fix QM_ASSIGN optimization, again --- Zend/Optimizer/block_pass.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index 058d1d0f7304a..06c7003cc8a3a 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -299,8 +299,11 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array ++(*opt_count); if (src->op1_type & (IS_VAR|IS_TMP_VAR)) { src->opcode = ZEND_FREE; - } else { + } 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: From 6babcab24b0e69d81b51a89cf5dced0fc49fa4f2 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Wed, 3 Dec 2025 00:11:19 +0100 Subject: [PATCH 13/19] Fix test --- ext/opcache/tests/opt/sccp_032.phpt | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/ext/opcache/tests/opt/sccp_032.phpt b/ext/opcache/tests/opt/sccp_032.phpt index 73ccb26654705..3db224845f303 100644 --- a/ext/opcache/tests/opt/sccp_032.phpt +++ b/ext/opcache/tests/opt/sccp_032.phpt @@ -44,13 +44,12 @@ LIVE RANGES: 1: 0003 - 0009 (loop) test: - ; (lines=5, args=0, vars=0, tmps=0) + ; (lines=4, args=0, vars=0, tmps=0) ; (after optimizer) ; %ssccp_032.php:2-9 0000 GENERATOR_CREATE -0001 YIELD_FROM array(...) -0002 YIELD null -0003 YIELD_FROM array(...) -0004 GENERATOR_RETURN null +0001 YIELD null +0002 YIELD_FROM array(...) +0003 GENERATOR_RETURN null NULL 3 From 545d56f9a38546fa9a79121fc78e28706d01b968 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Wed, 3 Dec 2025 00:15:29 +0100 Subject: [PATCH 14/19] Fix cufa array_slice optimization --- Zend/zend_compile.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 27a6b1b585e01..ff72409110e5a 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -4387,7 +4387,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; } From d63a4ffe10e58a3905d992422bb75c48ab699c8b Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 4 Dec 2025 20:01:02 +0100 Subject: [PATCH 15/19] Replace ZEND_DEREF with ZEND_QM_ASSIGN The op1=IS_VAR spec was pretty much identical, and there are most likely already better optimizations for QM_ASSIGN in place. --- Zend/Optimizer/dce.c | 1 - Zend/Optimizer/zend_inference.c | 1 - Zend/zend_compile.c | 8 +- Zend/zend_vm_def.h | 21 - Zend/zend_vm_execute.h | 236 ++++---- Zend/zend_vm_handlers.h | 935 ++++++++++++++++---------------- Zend/zend_vm_opcodes.c | 6 +- Zend/zend_vm_opcodes.h | 3 +- 8 files changed, 568 insertions(+), 643 deletions(-) diff --git a/Zend/Optimizer/dce.c b/Zend/Optimizer/dce.c index 14d014bc9e3c8..6c5a885fba405 100644 --- a/Zend/Optimizer/dce.c +++ b/Zend/Optimizer/dce.c @@ -125,7 +125,6 @@ static inline bool may_have_side_effects( case ZEND_FUNC_GET_ARGS: case ZEND_ARRAY_KEY_EXISTS: case ZEND_COPY_TMP: - case ZEND_DEREF: /* No side effects */ return false; case ZEND_FREE: diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index e5b6576944e5a..e50b7b36870a0 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -5033,7 +5033,6 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op case ZEND_COPY_TMP: case ZEND_JMP_NULL: case ZEND_JMP_FRAMELESS: - case ZEND_DEREF: return 0; case ZEND_IS_IDENTICAL: case ZEND_IS_NOT_IDENTICAL: diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index ff72409110e5a..0d586826ed1a9 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3407,7 +3407,8 @@ static void zend_compile_list_assign( if (result) { if ((type == BP_VAR_R || type == BP_VAR_IS) && expr_node->op_type == IS_VAR) { - zend_emit_op_tmp(result, ZEND_DEREF, expr_node, NULL); + /* Deref. */ + zend_emit_op_tmp(result, ZEND_QM_ASSIGN, expr_node, NULL); } else { *result = *expr_node; } @@ -3650,8 +3651,9 @@ static void zend_compile_assign_ref(znode *result, zend_ast *ast, uint32_t type) } if (result && (type == BP_VAR_R || type == BP_VAR_IS)) { + /* Deref. */ znode tmp_result = *result; - zend_emit_op_tmp(result, ZEND_DEREF, &tmp_result, NULL); + zend_emit_op_tmp(result, ZEND_QM_ASSIGN, &tmp_result, NULL); } } /* }}} */ @@ -10729,7 +10731,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); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index e0adcf13da39a..28ca69ea6facb 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -10006,27 +10006,6 @@ ZEND_VM_HANDLER(209, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL, CONST, UNUSED|NUM, NUM ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(211, ZEND_DEREF, VAR, UNUSED) -{ - USE_OPLINE - - zval *value = GET_OP1_ZVAL_PTR(BP_VAR_R); - - if (Z_TYPE_P(value) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(value); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(EX_VAR(opline->result.var)); - } - } else { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - } - - ZEND_VM_NEXT_OPCODE(); -} - ZEND_VM_HOT_TYPE_SPEC_HANDLER(ZEND_JMP, (OP_JMP_ADDR(op, op->op1) > op), ZEND_JMP_FORWARD, JMP_ADDR, ANY) { USE_OPLINE diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index cf166987408bc..a5ddf4e0d038e 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -30446,27 +30446,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_MAKE_REF_SPEC ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_DEREF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (Z_TYPE_P(value) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(value); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(EX_VAR(opline->result.var)); - } - } else { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - } - - ZEND_VM_NEXT_OPCODE(); -} - static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -83022,27 +83001,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_MAKE_REF_SPEC_VAR_ ZEND_VM_NEXT_OPCODE(); } -static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_DEREF_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) -{ - USE_OPLINE - - zval *value = _get_zval_ptr_var(opline->op1.var EXECUTE_DATA_CC); - - if (Z_TYPE_P(value) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(value); - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(EX_VAR(opline->result.var)); - } - } else { - ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); - } - - ZEND_VM_NEXT_OPCODE(); -} - static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -109457,7 +109415,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) (void*)&&ZEND_JMP_FRAMELESS_SPEC_CONST_LABEL, (void*)&&ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_LABEL, (void*)&&ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST_LABEL, - (void*)&&ZEND_DEREF_SPEC_VAR_UNUSED_LABEL, (void*)&&ZEND_INIT_FCALL_OFFSET_SPEC_CONST_LABEL, (void*)&&ZEND_RECV_NOTYPE_SPEC_LABEL, (void*)&&ZEND_NULL_LABEL, @@ -113820,11 +113777,6 @@ ZEND_API void execute_ex(zend_execute_data *ex) ZEND_MAKE_REF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); VM_TRACE_OP_END(ZEND_MAKE_REF_SPEC_VAR_UNUSED) HYBRID_BREAK(); - HYBRID_CASE(ZEND_DEREF_SPEC_VAR_UNUSED): - VM_TRACE(ZEND_DEREF_SPEC_VAR_UNUSED) - ZEND_DEREF_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - VM_TRACE_OP_END(ZEND_DEREF_SPEC_VAR_UNUSED) - HYBRID_BREAK(); HYBRID_CASE(ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED): VM_TRACE(ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -118395,7 +118347,6 @@ void zend_vm_init(void) ZEND_JMP_FRAMELESS_SPEC_CONST_HANDLER, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_HANDLER, ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST_HANDLER, - ZEND_DEREF_SPEC_VAR_UNUSED_HANDLER, ZEND_INIT_FCALL_OFFSET_SPEC_CONST_HANDLER, ZEND_RECV_NOTYPE_SPEC_HANDLER, ZEND_NULL_HANDLER, @@ -121873,7 +121824,6 @@ void zend_vm_init(void) ZEND_JMP_FRAMELESS_SPEC_CONST_TAILCALL_HANDLER, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED_TAILCALL_HANDLER, ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST_TAILCALL_HANDLER, - ZEND_DEREF_SPEC_VAR_UNUSED_TAILCALL_HANDLER, ZEND_INIT_FCALL_OFFSET_SPEC_CONST_TAILCALL_HANDLER, ZEND_RECV_NOTYPE_SPEC_TAILCALL_HANDLER, ZEND_NULL_TAILCALL_HANDLER, @@ -122842,7 +122792,7 @@ void zend_vm_init(void) 1255, 1256 | SPEC_RULE_OP1, 1261 | SPEC_RULE_OP1, - 3474, + 3473, 1266 | SPEC_RULE_OP1, 1271 | SPEC_RULE_OP1, 1276 | SPEC_RULE_OP2, @@ -122876,7 +122826,7 @@ void zend_vm_init(void) 1559 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1584 | SPEC_RULE_OP1, 1589, - 3474, + 3473, 1590 | SPEC_RULE_OP1, 1595 | SPEC_RULE_OP1 | SPEC_RULE_OP2, 1620 | SPEC_RULE_OP1 | SPEC_RULE_OP2, @@ -123008,51 +122958,51 @@ void zend_vm_init(void) 2555, 2556, 2557, - 2558, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, - 3474, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, + 3473, }; #if 0 #elif (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID) @@ -123229,7 +123179,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2567 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2566 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -123237,7 +123187,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2592 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2591 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -123245,7 +123195,7 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2617 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2616 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; if (op->op1_type < op->op2_type) { zend_swap_operands(op); } @@ -123256,17 +123206,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2642 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2641 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2667 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2666 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2692 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 2691 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_MUL: @@ -123277,17 +123227,17 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2717 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2716 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2742 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2741 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2767 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 2766 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_IDENTICAL: @@ -123298,16 +123248,16 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2792 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2791 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2867 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2866 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op2_type == IS_CONST && (Z_TYPE_P(RT_CONSTANT(op, op->op2)) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(RT_CONSTANT(op, op->op2))) == 0)) { - spec = 3092 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3091 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) { - spec = 3098 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3097 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_IDENTICAL: @@ -123318,16 +123268,16 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2942 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2941 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3017 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3016 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op2_type == IS_CONST && (Z_TYPE_P(RT_CONSTANT(op, op->op2)) == IS_ARRAY && zend_hash_num_elements(Z_ARR_P(RT_CONSTANT(op, op->op2))) == 0)) { - spec = 3095 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3094 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) { - spec = 3103 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; + spec = 3102 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_EQUAL: @@ -123338,12 +123288,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2792 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2791 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2867 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2866 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_NOT_EQUAL: @@ -123354,12 +123304,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 2942 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 2941 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3017 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; + spec = 3016 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE; } break; case ZEND_IS_SMALLER: @@ -123367,12 +123317,12 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3108 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3107 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3183 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3182 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_IS_SMALLER_OR_EQUAL: @@ -123380,79 +123330,79 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3258 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3257 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) { if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3333 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; + spec = 3332 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH; } break; case ZEND_QM_ASSIGN: if (op1_info == MAY_BE_LONG) { - spec = 3420 | SPEC_RULE_OP1; + spec = 3419 | SPEC_RULE_OP1; } else if (op1_info == MAY_BE_DOUBLE) { - spec = 3425 | SPEC_RULE_OP1; + spec = 3424 | SPEC_RULE_OP1; } else if ((op->op1_type == IS_CONST) ? !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1)) : (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE))))) { - spec = 3430 | SPEC_RULE_OP1; + spec = 3429 | SPEC_RULE_OP1; } break; case ZEND_PRE_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3408 | SPEC_RULE_RETVAL; + spec = 3407 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3410 | SPEC_RULE_RETVAL; + spec = 3409 | SPEC_RULE_RETVAL; } break; case ZEND_PRE_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3412 | SPEC_RULE_RETVAL; + spec = 3411 | SPEC_RULE_RETVAL; } else if (op1_info == MAY_BE_LONG) { - spec = 3414 | SPEC_RULE_RETVAL; + spec = 3413 | SPEC_RULE_RETVAL; } break; case ZEND_POST_INC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3416; + spec = 3415; } else if (op1_info == MAY_BE_LONG) { - spec = 3417; + spec = 3416; } break; case ZEND_POST_DEC: if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) { - spec = 3418; + spec = 3417; } else if (op1_info == MAY_BE_LONG) { - spec = 3419; + spec = 3418; } break; case ZEND_JMP: if (OP_JMP_ADDR(op, op->op1) > op) { - spec = 2566; + spec = 2565; } break; case ZEND_INIT_FCALL: if (Z_EXTRA_P(RT_CONSTANT(op, op->op2)) != 0) { - spec = 2559; + spec = 2558; } break; case ZEND_RECV: if (op->op2.num == MAY_BE_ANY) { - spec = 2560; + spec = 2559; } break; case ZEND_SEND_VAL: if (op->op1_type == IS_CONST && op->op2_type == IS_UNUSED && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { - spec = 3470; + spec = 3469; } break; case ZEND_SEND_VAR_EX: if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3465 | SPEC_RULE_OP1; + spec = 3464 | SPEC_RULE_OP1; } break; case ZEND_FE_FETCH_R: if (op->op2_type == IS_CV && (op1_info & (MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) { - spec = 3472 | SPEC_RULE_RETVAL; + spec = 3471 | SPEC_RULE_RETVAL; } break; case ZEND_FETCH_DIM_R: @@ -123460,22 +123410,22 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) { break; } - spec = 3435 | SPEC_RULE_OP1 | SPEC_RULE_OP2; + spec = 3434 | SPEC_RULE_OP1 | SPEC_RULE_OP2; } break; case ZEND_SEND_VAL_EX: if (op->op2_type == IS_UNUSED && op->op2.num <= MAX_ARG_FLAG_NUM && op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) { - spec = 3471; + spec = 3470; } break; case ZEND_SEND_VAR: if (op->op2_type == IS_UNUSED && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) { - spec = 3460 | SPEC_RULE_OP1; + spec = 3459 | SPEC_RULE_OP1; } break; case ZEND_COUNT: if ((op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) == MAY_BE_ARRAY) { - spec = 2561 | SPEC_RULE_OP1; + spec = 2560 | SPEC_RULE_OP1; } break; case ZEND_BW_OR: diff --git a/Zend/zend_vm_handlers.h b/Zend/zend_vm_handlers.h index 16db986c334c3..32953c96f1d41 100644 --- a/Zend/zend_vm_handlers.h +++ b/Zend/zend_vm_handlers.h @@ -1086,508 +1086,507 @@ _(2555, ZEND_JMP_FRAMELESS_SPEC_CONST) \ _(2556, ZEND_INIT_PARENT_PROPERTY_HOOK_CALL_SPEC_CONST_UNUSED) \ _(2557, ZEND_DECLARE_ATTRIBUTED_CONST_SPEC_CONST_CONST) \ - _(2558, ZEND_DEREF_SPEC_VAR_UNUSED) \ - _(2559, ZEND_INIT_FCALL_OFFSET_SPEC_CONST) \ - _(2560, ZEND_RECV_NOTYPE_SPEC) \ - _(2562, ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED) \ - _(2565, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED) \ - _(2566, ZEND_JMP_FORWARD_SPEC) \ - _(2572, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2558, ZEND_INIT_FCALL_OFFSET_SPEC_CONST) \ + _(2559, ZEND_RECV_NOTYPE_SPEC) \ + _(2561, ZEND_COUNT_ARRAY_SPEC_TMP_UNUSED) \ + _(2564, ZEND_COUNT_ARRAY_SPEC_CV_UNUSED) \ + _(2565, ZEND_JMP_FORWARD_SPEC) \ + _(2571, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2572, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2573, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2574, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2576, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2577, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2575, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2576, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2577, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2578, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2579, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2581, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2587, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2580, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2586, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2587, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2588, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2589, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2591, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2597, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2590, ZEND_ADD_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2596, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2597, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2598, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2599, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2601, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2602, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2600, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2601, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2602, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2603, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2604, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2606, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2612, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2605, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2611, ZEND_ADD_LONG_SPEC_TMPVARCV_CONST) \ + _(2612, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2613, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2614, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2616, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2622, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2615, ZEND_ADD_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2621, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2622, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2623, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2624, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2626, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2627, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2625, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2626, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2627, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2628, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2629, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2631, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2637, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2630, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2636, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2637, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2638, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2639, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2641, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2640, ZEND_ADD_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2642, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ _(2643, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2644, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2646, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ - _(2647, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2645, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_CONST_TMPVARCV) \ + _(2646, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2647, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2648, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2649, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2651, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2652, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2650, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2651, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2652, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2653, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2654, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2656, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2662, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2655, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2661, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2662, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2663, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2664, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2666, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2665, ZEND_SUB_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2667, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ _(2668, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2669, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2671, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ - _(2672, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2670, ZEND_SUB_LONG_SPEC_CONST_TMPVARCV) \ + _(2671, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2672, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2673, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2674, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2676, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2677, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2675, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2676, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2677, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2678, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2679, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2681, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2687, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2680, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2686, ZEND_SUB_LONG_SPEC_TMPVARCV_CONST) \ + _(2687, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2688, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2689, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2691, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2690, ZEND_SUB_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2692, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ _(2693, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2694, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2696, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(2697, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2695, ZEND_SUB_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(2696, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2697, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2698, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2699, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2701, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2702, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2700, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2701, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2702, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2703, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2704, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2706, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2712, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2705, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2711, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2712, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2713, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2714, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2716, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2722, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2715, ZEND_SUB_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2721, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2722, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2723, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2724, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2726, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2727, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2725, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2726, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2727, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2728, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2729, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2731, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2737, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2730, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2736, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_CONST) \ + _(2737, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ _(2738, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2739, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2741, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ - _(2747, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2740, ZEND_MUL_LONG_NO_OVERFLOW_SPEC_TMPVARCV_TMPVARCV) \ + _(2746, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2747, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2748, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2749, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2751, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2752, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2750, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2751, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2752, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2753, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2754, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2756, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2762, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2755, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2761, ZEND_MUL_LONG_SPEC_TMPVARCV_CONST) \ + _(2762, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ _(2763, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2764, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2766, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2772, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2765, ZEND_MUL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2771, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2772, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2773, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2774, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2776, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2777, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2775, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2776, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2777, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2778, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2779, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2781, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2787, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2780, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2786, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2787, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ _(2788, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2789, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2791, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2807, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2808, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2809, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2810, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2811, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2812, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2813, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2814, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2815, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2819, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2820, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2821, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2822, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2823, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2824, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2825, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2826, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2827, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2828, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2829, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2830, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2834, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2835, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2836, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2852, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2853, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2854, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2855, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2856, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2857, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2858, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2859, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2860, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2864, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2865, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2866, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2882, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2883, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2884, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2885, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2886, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2887, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2888, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2889, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2890, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2894, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2895, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2896, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2897, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2898, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2899, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2900, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2901, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2902, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2903, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2904, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2905, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2909, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2910, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2911, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2927, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(2928, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2929, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2930, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2931, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2932, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2933, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2934, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2935, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2939, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(2940, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2941, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2957, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2958, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2959, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2960, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2961, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2962, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2963, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2964, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2965, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2969, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2970, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2971, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2972, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(2973, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(2974, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(2975, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2976, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2977, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2978, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2979, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2980, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(2984, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(2985, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(2986, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3002, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3003, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3004, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3005, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3006, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3007, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3008, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3009, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3010, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3014, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3015, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3016, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3032, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3033, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3034, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3035, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3036, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3037, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3038, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3039, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3040, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3044, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3045, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3046, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3047, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3048, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3049, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3050, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3051, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3052, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3053, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3054, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3055, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3059, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3060, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3061, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3077, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3078, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3079, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3080, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3081, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3082, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3083, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3084, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3085, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3089, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3090, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3091, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3092, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST) \ - _(3093, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3094, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3095, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST) \ - _(3096, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3097, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3098, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3102, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3103, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ - _(3107, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ - _(3111, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3112, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3113, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3114, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3115, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3116, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3120, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ - _(3121, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3122, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3123, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3124, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3125, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3126, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3127, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3128, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3129, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3130, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3131, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3135, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3136, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3137, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3138, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3139, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3140, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3141, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3144, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3145, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3146, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3151, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3152, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3168, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ - _(3169, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3170, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3171, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3172, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3173, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3174, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3175, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3176, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3180, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3181, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3182, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3186, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3187, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3188, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3189, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3190, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3191, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3195, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3196, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3197, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3198, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3199, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3200, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3201, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3202, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3203, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3204, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3205, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3206, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3210, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3211, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3212, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3213, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3214, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3215, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3216, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3219, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3220, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3221, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3226, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3227, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3243, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3244, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3245, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3246, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3247, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3248, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3249, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3250, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3251, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3255, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3256, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3257, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3261, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3262, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3263, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3264, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3265, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3266, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3270, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ - _(3271, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3272, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3273, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3274, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3276, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3277, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3278, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3279, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3280, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3281, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3285, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3286, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3287, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3288, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3289, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3290, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3291, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3294, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3295, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3296, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3301, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3302, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3318, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ - _(3319, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3320, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3321, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3322, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3323, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3324, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3325, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3326, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3330, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ - _(3331, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3332, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3336, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3337, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3338, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3339, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3340, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3341, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3345, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ - _(3346, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ - _(3347, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ - _(3348, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3349, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3351, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3352, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3353, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3354, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3355, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3356, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3360, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3361, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3362, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3363, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3364, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3365, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3366, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3369, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3370, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3371, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3376, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3377, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3393, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ - _(3394, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ - _(3395, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ - _(3396, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3397, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3398, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3399, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3400, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3401, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3405, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ - _(3406, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ - _(3407, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ - _(3408, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3409, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3410, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3411, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ - _(3412, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ - _(3413, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ - _(3414, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ - _(3415, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ - _(3416, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3417, ZEND_POST_INC_LONG_SPEC_CV) \ - _(3418, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ - _(3419, ZEND_POST_DEC_LONG_SPEC_CV) \ - _(3420, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ + _(2790, ZEND_MUL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2806, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2807, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2808, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2809, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2810, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2811, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2812, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2813, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2814, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2818, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2819, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2820, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2821, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2822, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2823, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2824, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2825, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2826, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2827, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2828, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2829, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2833, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2834, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2835, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2851, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2852, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2853, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2854, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2855, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2856, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2857, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2858, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2859, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2863, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2864, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2865, ZEND_IS_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2881, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2882, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2883, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2884, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2885, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2886, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2887, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2888, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2889, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2893, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2894, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2895, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2896, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2897, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2898, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2899, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2900, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2901, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2902, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2903, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2904, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2908, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2909, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2910, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2926, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(2927, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2928, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2929, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2930, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2931, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2932, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2933, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2934, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2938, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(2939, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2940, ZEND_IS_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2956, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2957, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2958, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2959, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2960, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2961, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2962, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2963, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2964, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2968, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2969, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2970, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2971, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(2972, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(2973, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(2974, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2975, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2976, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2977, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2978, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2979, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(2983, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(2984, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(2985, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3001, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3002, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3003, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3004, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3005, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3006, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3007, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3008, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3009, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3013, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3014, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3015, ZEND_IS_NOT_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3031, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3032, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3033, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3034, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3035, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3036, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3037, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3038, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3039, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3043, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3044, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3045, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3046, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3047, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3048, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3049, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3050, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3051, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3052, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3053, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3054, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3058, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3059, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3060, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3076, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3077, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3078, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3079, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3080, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3081, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3082, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3083, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3084, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3088, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3089, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3090, ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3091, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST) \ + _(3092, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3093, ZEND_IS_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3094, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST) \ + _(3095, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3096, ZEND_IS_NOT_IDENTICAL_EMPTY_ARRAY_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3097, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3101, ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3102, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST) \ + _(3106, ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV) \ + _(3110, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3111, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3112, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3113, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3114, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3115, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3119, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV) \ + _(3120, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3121, ZEND_IS_SMALLER_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3122, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3123, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3124, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3125, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3126, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3127, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3128, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3129, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3130, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3134, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3135, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3136, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3137, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3138, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3139, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3140, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3141, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3142, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3143, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3144, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3145, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3149, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3150, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3151, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3167, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST) \ + _(3168, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3169, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3170, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3171, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3172, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3173, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3174, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3175, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3179, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3180, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3181, ZEND_IS_SMALLER_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3185, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3186, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3187, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3188, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3189, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3190, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3194, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3195, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3196, ZEND_IS_SMALLER_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3197, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3198, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3199, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3200, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3201, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3202, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3203, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3204, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3205, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3209, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3210, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3211, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3212, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3213, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3214, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3215, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3216, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3217, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3218, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3219, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3220, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3224, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3225, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3226, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3242, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3243, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3244, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3245, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3246, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3247, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3248, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3249, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3250, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3254, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3255, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3256, ZEND_IS_SMALLER_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3260, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3261, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3262, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3263, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3264, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3265, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3269, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV) \ + _(3270, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3271, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3272, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3273, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3274, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3275, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3276, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3277, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3278, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3279, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3280, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3284, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3285, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3286, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3287, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3288, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3289, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3290, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3291, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3292, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3293, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3294, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3295, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3299, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3300, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3301, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3317, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST) \ + _(3318, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3319, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3320, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3321, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3322, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3323, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3324, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3325, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3329, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV) \ + _(3330, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3331, ZEND_IS_SMALLER_OR_EQUAL_LONG_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3335, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3336, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3337, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3338, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3339, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3340, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3344, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV) \ + _(3345, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPZ) \ + _(3346, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_CONST_TMPVARCV_JMPNZ) \ + _(3347, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3348, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3349, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3350, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3351, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3352, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3353, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3354, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3355, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3359, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3360, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3361, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3362, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3363, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3364, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3365, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3366, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3367, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3368, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3369, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3370, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3374, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3375, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3376, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3392, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST) \ + _(3393, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPZ) \ + _(3394, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_CONST_JMPNZ) \ + _(3395, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3396, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3397, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3398, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3399, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3400, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3404, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV) \ + _(3405, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ) \ + _(3406, ZEND_IS_SMALLER_OR_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ) \ + _(3407, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3408, ZEND_PRE_INC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3409, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3410, ZEND_PRE_INC_LONG_SPEC_CV_RETVAL_USED) \ + _(3411, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_UNUSED) \ + _(3412, ZEND_PRE_DEC_LONG_NO_OVERFLOW_SPEC_CV_RETVAL_USED) \ + _(3413, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_UNUSED) \ + _(3414, ZEND_PRE_DEC_LONG_SPEC_CV_RETVAL_USED) \ + _(3415, ZEND_POST_INC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3416, ZEND_POST_INC_LONG_SPEC_CV) \ + _(3417, ZEND_POST_DEC_LONG_NO_OVERFLOW_SPEC_CV) \ + _(3418, ZEND_POST_DEC_LONG_SPEC_CV) \ + _(3419, ZEND_QM_ASSIGN_LONG_SPEC_CONST) \ + _(3420, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ _(3421, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3422, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3424, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ - _(3425, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ + _(3423, ZEND_QM_ASSIGN_LONG_SPEC_TMPVARCV) \ + _(3424, ZEND_QM_ASSIGN_DOUBLE_SPEC_CONST) \ + _(3425, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ _(3426, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3427, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3429, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ - _(3430, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ + _(3428, ZEND_QM_ASSIGN_DOUBLE_SPEC_TMPVARCV) \ + _(3429, ZEND_QM_ASSIGN_NOREF_SPEC_CONST) \ + _(3430, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ _(3431, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3432, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ - _(3434, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3433, ZEND_QM_ASSIGN_NOREF_SPEC_TMPVARCV) \ + _(3435, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ _(3436, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3437, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3439, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ - _(3440, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3438, ZEND_FETCH_DIM_R_INDEX_SPEC_CONST_TMPVARCV) \ + _(3439, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3440, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3441, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3442, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3444, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3445, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3443, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3444, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_CONST) \ + _(3445, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ _(3446, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3447, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3449, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ - _(3455, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ + _(3448, ZEND_FETCH_DIM_R_INDEX_SPEC_TMPVAR_TMPVARCV) \ + _(3454, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST) \ + _(3455, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ _(3456, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3457, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3459, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ - _(3462, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ - _(3464, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ - _(3467, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ - _(3469, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ - _(3470, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ - _(3471, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ - _(3472, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ - _(3473, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ - _(3473+1, ZEND_NULL) + _(3458, ZEND_FETCH_DIM_R_INDEX_SPEC_CV_TMPVARCV) \ + _(3461, ZEND_SEND_VAR_SIMPLE_SPEC_VAR) \ + _(3463, ZEND_SEND_VAR_SIMPLE_SPEC_CV) \ + _(3466, ZEND_SEND_VAR_EX_SIMPLE_SPEC_VAR_UNUSED) \ + _(3468, ZEND_SEND_VAR_EX_SIMPLE_SPEC_CV_UNUSED) \ + _(3469, ZEND_SEND_VAL_SIMPLE_SPEC_CONST) \ + _(3470, ZEND_SEND_VAL_EX_SIMPLE_SPEC_CONST) \ + _(3471, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_UNUSED) \ + _(3472, ZEND_FE_FETCH_R_SIMPLE_SPEC_VAR_CV_RETVAL_USED) \ + _(3472+1, ZEND_NULL) diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 944f359a7b268..0d4e72d8a0ecf 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -22,7 +22,7 @@ #include #include -static const char *zend_vm_opcodes_names[212] = { +static const char *zend_vm_opcodes_names[211] = { "ZEND_NOP", "ZEND_ADD", "ZEND_SUB", @@ -234,10 +234,9 @@ static const char *zend_vm_opcodes_names[212] = { "ZEND_JMP_FRAMELESS", "ZEND_INIT_PARENT_PROPERTY_HOOK_CALL", "ZEND_DECLARE_ATTRIBUTED_CONST", - "ZEND_DEREF", }; -static uint32_t zend_vm_opcodes_flags[212] = { +static uint32_t zend_vm_opcodes_flags[211] = { 0x00000000, 0x00000b0b, 0x00000b0b, @@ -449,7 +448,6 @@ static uint32_t zend_vm_opcodes_flags[212] = { 0x01042003, 0x01001103, 0x00000303, - 0x00000101, }; ZEND_API const char* ZEND_FASTCALL zend_get_opcode_name(uint8_t opcode) { diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index f1a1eb8b6dc94..287dec375f3a9 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -330,8 +330,7 @@ END_EXTERN_C() #define ZEND_JMP_FRAMELESS 208 #define ZEND_INIT_PARENT_PROPERTY_HOOK_CALL 209 #define ZEND_DECLARE_ATTRIBUTED_CONST 210 -#define ZEND_DEREF 211 -#define ZEND_VM_LAST_OPCODE 211 +#define ZEND_VM_LAST_OPCODE 210 #endif From 4ad5861e6c3f4d84d20144ac9e83b95481b74367 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 4 Dec 2025 20:03:35 +0100 Subject: [PATCH 16/19] Revert unneded change --- ext/opcache/jit/zend_jit_ir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index 0bcf972447a93..1c5cab899e783 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -10078,7 +10078,7 @@ static int zend_jit_do_fcall(zend_jit_ctx *jit, const zend_op *opline, const zen } bool may_have_extra_named_params = - (opline->extended_value & ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS) && + opline->extended_value == ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS && (!func || func->common.fn_flags & ZEND_ACC_VARIADIC); if (!jit->reuse_ip) { From 448ce15eb78624624a34f09ee64e843fa6d6dd7d Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 4 Dec 2025 20:19:49 +0100 Subject: [PATCH 17/19] Use zend_unwrap_reference() in zend_return_unwrap_ref() --- Zend/zend_execute.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 99a63a129ad35..02220750dd7df 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -5971,11 +5971,5 @@ ZEND_API void zend_return_unwrap_ref(zend_execute_data *execute_data, zval *retu return; } - zend_reference *ref = Z_REF_P(return_value); - ZVAL_COPY_VALUE(return_value, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(return_value); - } + zend_unwrap_reference(return_value); } From 84919491d9430451ad7a3cc54469c72ce154c069 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 4 Dec 2025 20:31:48 +0100 Subject: [PATCH 18/19] Simplify condition --- Zend/zend_compile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 0d586826ed1a9..b7ea86aa170af 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3850,7 +3850,7 @@ 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)) { - uint32_t type = is_globals_fetch(arg) || (fbc && !ARG_MUST_BE_SENT_BY_REF(fbc, arg_num) && !ARG_MAY_BE_SENT_BY_REF(fbc, arg_num)) + 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, false); if (arg_node.op_type & (IS_CONST|IS_TMP_VAR)) { From 30e866d73bd99272aa998f32a3f322f71e1f9673 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Thu, 4 Dec 2025 21:53:08 +0100 Subject: [PATCH 19/19] Various tweaks --- Zend/tests/gh20628_001.phpt | 12 + Zend/tests/gh20628_002.phpt | 22 ++ Zend/zend_compile.c | 25 +- Zend/zend_vm_def.h | 24 +- Zend/zend_vm_execute.h | 520 +++++------------------------------- 5 files changed, 121 insertions(+), 482 deletions(-) create mode 100644 Zend/tests/gh20628_001.phpt create mode 100644 Zend/tests/gh20628_002.phpt diff --git a/Zend/tests/gh20628_001.phpt b/Zend/tests/gh20628_001.phpt new file mode 100644 index 0000000000000..7b9534c9713bb --- /dev/null +++ b/Zend/tests/gh20628_001.phpt @@ -0,0 +1,12 @@ +--TEST-- +Nullsafe operator does not support BP_VAR_W +--FILE-- +bar(); +} + +?> +--EXPECTF-- +Fatal error: Cannot take reference of a nullsafe chain in %s on line %d diff --git a/Zend/tests/gh20628_002.phpt b/Zend/tests/gh20628_002.phpt new file mode 100644 index 0000000000000..509db5ff3d6c1 --- /dev/null +++ b/Zend/tests/gh20628_002.phpt @@ -0,0 +1,22 @@ +--TEST-- +Pipes support return-by-reference +--FILE-- + foo(...); +} + +$xRef = &bar(); +$xRef++; +var_dump($x); + +?> +--EXPECT-- +int(43) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index b7ea86aa170af..a38954242bf5d 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2600,8 +2600,7 @@ static void zend_emit_jmp_null(znode *obj_node, uint32_t bp_type) zend_stack_push(&CG(short_circuiting_opnums), &jmp_null_opnum); } -static inline bool zend_is_variable(const zend_ast *ast); -static inline bool zend_is_call(const zend_ast *ast); +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) /* {{{ */ { @@ -2611,8 +2610,8 @@ static void zend_compile_memoized_expr(znode *result, zend_ast *expr, uint32_t t /* Go through normal compilation */ CG(memoize_mode) = ZEND_MEMOIZE_NONE; - if (zend_is_variable(expr) || zend_is_call(expr)) { - zend_compile_var(result, expr, type, false); + if (zend_is_variable_or_call(expr)) { + zend_compile_var(result, expr, type, /* by_ref */ false); } else { zend_compile_expr(result, expr); } @@ -3852,7 +3851,7 @@ static uint32_t zend_compile_args( if (zend_is_call(arg) || is_globals_fetch(arg)) { 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, false); + 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)) { @@ -4053,7 +4052,6 @@ 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; @@ -4061,7 +4059,7 @@ static bool zend_compile_call_common(znode *result, zend_ast *args_ast, const ze } } if (may_have_extra_named_args) { - opline->extended_value |= ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS; + opline->extended_value = ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS; } opline->lineno = lineno; zend_do_extended_fcall_end(); @@ -4404,11 +4402,11 @@ 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); - opline->extended_value |= ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS; 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; } @@ -5870,8 +5868,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); - // FIXME: Shouldn't apply to nullsafe calls and pipes. - } else if (by_ref && (zend_is_variable(expr_ast) || zend_is_call(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 { @@ -6710,7 +6707,7 @@ static void zend_compile_pipe(znode *result, zend_ast *ast, uint32_t type) zend_do_extended_stmt(&operand_result); - zend_compile_var(result, fcall_ast, type, false); + zend_compile_var(result, fcall_ast, type, /* by_ref */ false); } static void zend_compile_match(znode *result, zend_ast *ast) @@ -10907,7 +10904,7 @@ static void zend_compile_yield(znode *result, zend_ast *ast) /* {{{ */ } if (value_ast) { - if (returns_by_ref && (zend_is_variable(value_ast) || zend_is_call(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 { @@ -11966,7 +11963,7 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */ break; case ZEND_AST_ASSIGN: { znode result; - zend_compile_assign(&result, ast, true); + zend_compile_assign(&result, ast, /* stmt */ true); zend_do_free(&result); return; } @@ -12019,7 +12016,7 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */ zend_compile_var(result, ast, BP_VAR_R, false); return; case ZEND_AST_ASSIGN: - zend_compile_assign(result, ast, false); + zend_compile_assign(result, ast, /* stmt */ false); return; case ZEND_AST_ASSIGN_REF: zend_compile_assign_ref(result, ast, BP_VAR_R); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 28ca69ea6facb..4d787dbbe59a2 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2054,13 +2054,7 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, C if (OP1_TYPE & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_DIM_R); @@ -2432,13 +2426,7 @@ ZEND_VM_COLD_CONST_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THI if (OP1_TYPE == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_OBJ_R); @@ -4680,7 +4668,6 @@ 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(); - // FIXME: Don't create the ref in the first place? zend_return_unwrap_ref(execute_data, return_value); ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper); @@ -7279,9 +7266,10 @@ ZEND_VM_HOT_HANDLER(78, ZEND_FE_FETCH_R, TMP, ANY, JMP_ADDR) zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - ZVAL_DEREF(value); - value_type = Z_TYPE_INFO_P(value); - + 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); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index a5ddf4e0d038e..74604c017639c 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -4912,7 +4912,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ - // FIXME: Don't create the ref in the first place? zend_return_unwrap_ref(execute_data, return_value); ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -4982,7 +4981,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ zend_observer_fcall_end(execute_data, return_value); if (return_value == &observer_retval) { zval_ptr_dtor_nogc(&observer_retval); }; - // FIXME: Don't create the ref in the first place? zend_return_unwrap_ref(execute_data, return_value); ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -6825,13 +6823,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ if (IS_CONST & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -7155,13 +7147,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ if (IS_CONST == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -9580,13 +9566,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if (IS_CONST & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -9908,13 +9888,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ if (IS_CONST == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -10997,13 +10971,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if (IS_CONST & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -12196,13 +12164,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if (IS_CONST & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -12526,13 +12488,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_ if (IS_CONST == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -17218,7 +17174,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_BY_REF - // FIXME: Don't create the ref in the first place? zend_return_unwrap_ref(execute_data, return_value); ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -17802,9 +17757,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_F zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - ZVAL_DEREF(value); - value_type = Z_TYPE_INFO_P(value); - + 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); @@ -18810,13 +18766,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if (IS_TMP_VAR & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -18839,13 +18789,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUN if (IS_TMP_VAR == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -20404,13 +20348,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if (IS_TMP_VAR & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -20433,13 +20371,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUN if (IS_TMP_VAR == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -21486,13 +21418,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if (IS_TMP_VAR & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -22272,13 +22198,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if (IS_TMP_VAR & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -22301,13 +22221,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUN if (IS_TMP_VAR == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -23501,7 +23415,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_BY_REF - // FIXME: Don't create the ref in the first place? zend_return_unwrap_ref(execute_data, return_value); ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -24314,13 +24227,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if (IS_VAR & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -24399,13 +24306,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUN if (IS_VAR == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -27036,13 +26937,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if (IS_VAR & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -27118,13 +27013,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUN if (IS_VAR == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -28960,13 +28849,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if (IS_VAR & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -30872,13 +30755,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if (IS_VAR & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -30957,13 +30834,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUN if (IS_VAR == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -33518,13 +33389,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUN if (IS_UNUSED == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -35621,13 +35486,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUN if (IS_UNUSED == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -38193,13 +38052,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUN if (IS_UNUSED == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -39976,7 +39829,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_RETURN_BY_REF - // FIXME: Don't create the ref in the first place? zend_return_unwrap_ref(execute_data, return_value); ZEND_VM_TAIL_CALL(zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -42184,13 +42036,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if (IS_CV & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -42575,13 +42421,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUN if (IS_CV == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -46028,13 +45868,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if (IS_CV & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -46409,13 +46243,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUN if (IS_CV == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -48742,13 +48570,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if (IS_CV & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -51152,13 +50974,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_DIM_FUN if (IS_CV & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -51538,13 +51354,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_FUNC_CCONV ZEND_FETCH_OBJ_FUN if (IS_CV == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -57669,7 +57479,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETUR - // FIXME: Don't create the ref in the first place? zend_return_unwrap_ref(execute_data, return_value); ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); @@ -57739,7 +57548,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETUR zend_observer_fcall_end(execute_data, return_value); if (return_value == &observer_retval) { zval_ptr_dtor_nogc(&observer_retval); }; - // FIXME: Don't create the ref in the first place? zend_return_unwrap_ref(execute_data, return_value); ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); @@ -59582,13 +59390,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH if (IS_CONST & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -59912,13 +59714,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH if (IS_CONST == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -62337,13 +62133,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_CONST & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -62665,13 +62455,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH if (IS_CONST == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -63652,13 +63436,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_CONST & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -64851,13 +64629,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_CONST & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -65181,13 +64953,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH if (IS_CONST == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CONST_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -69873,7 +69639,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_BY_REF_SPEC - // FIXME: Don't create the ref in the first place? zend_return_unwrap_ref(execute_data, return_value); ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); @@ -70457,9 +70222,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FE_FET zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES()); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } else { - ZVAL_DEREF(value); - value_type = Z_TYPE_INFO_P(value); - + 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); @@ -71465,13 +71231,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_TMP_VAR & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -71494,13 +71254,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG if (IS_TMP_VAR == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -73059,13 +72813,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_TMP_VAR & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -73088,13 +72836,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG if (IS_TMP_VAR == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -74041,13 +73783,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_TMP_VAR & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -74827,13 +74563,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_TMP_VAR & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -74856,13 +74586,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG if (IS_TMP_VAR == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -76056,7 +75780,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_BY_REF_SPEC - // FIXME: Don't create the ref in the first place? zend_return_unwrap_ref(execute_data, return_value); ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); @@ -76869,13 +76592,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_VAR & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -76954,13 +76671,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG if (IS_VAR == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -79591,13 +79302,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_VAR & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -79673,13 +79378,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG if (IS_VAR == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -81515,13 +81214,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_VAR & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -83427,13 +83120,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_VAR & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -83512,13 +83199,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG if (IS_VAR == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -86073,13 +85754,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG if (IS_UNUSED == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -88176,13 +87851,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG if (IS_UNUSED == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -90748,13 +90417,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG if (IS_UNUSED == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -92531,7 +92194,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_RETURN_BY_REF_SPEC - // FIXME: Don't create the ref in the first place? zend_return_unwrap_ref(execute_data, return_value); ZEND_VM_DISPATCH_TO_LEAVE_HELPER(zend_leave_helper_SPEC_TAILCALL); @@ -94739,13 +94401,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_CV & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -95130,13 +94786,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG if (IS_CV == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CONST_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -98583,13 +98233,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_CV & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -98964,13 +98608,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG if (IS_CV == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_TMP_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -101195,13 +100833,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_CV & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_NULL_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -103605,13 +103237,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_DIM_FUNC_ARG if (IS_CV & IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_DIM_R_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); @@ -103991,13 +103617,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_OPCODE_HANDLER_CCONV ZEND_FETCH_OBJ_FUNC_ARG if (IS_CV == IS_VAR) { zval *op1 = EX_VAR(opline->op1.var); if (Z_TYPE_P(op1) == IS_REFERENCE) { - zend_reference *ref = Z_REF_P(op1); - ZVAL_COPY_VALUE(op1, &ref->val); - if (GC_DELREF(ref) == 0) { - efree_size(ref, sizeof(zend_reference)); - } else { - Z_TRY_ADDREF_P(op1); - } + zend_unwrap_reference(op1); } } ZEND_VM_TAIL_CALL(ZEND_FETCH_OBJ_R_SPEC_CV_CV_TAILCALL_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU));