From 34ff6bbb0df152694e648161b149d41270fccdcb Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 19 Feb 2015 10:50:03 +0100 Subject: [PATCH 01/59] this line got accitentally dropped on merge --- main/output.c | 1 + 1 file changed, 1 insertion(+) diff --git a/main/output.c b/main/output.c index 64729ac4a49..22ac26a7c58 100644 --- a/main/output.c +++ b/main/output.c @@ -180,6 +180,7 @@ PHPAPI void php_output_deactivate(void) php_output_handler **handler = NULL; if ((OG(flags) & PHP_OUTPUT_ACTIVATED)) { + php_output_header(); OG(flags) ^= PHP_OUTPUT_ACTIVATED; OG(active) = NULL; From 543f0112055ed170d61738d301db9e509b44630c Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Thu, 19 Feb 2015 23:02:04 +0100 Subject: [PATCH 02/59] add NEWS for <=> --- NEWS | 1 + UPGRADING | 2 ++ 2 files changed, 3 insertions(+) diff --git a/NEWS b/NEWS index fdbd25bbe2d..bc93ebcb74d 100644 --- a/NEWS +++ b/NEWS @@ -34,6 +34,7 @@ . Implemented FR #55467 (phpinfo: PHP Variables with $ and single quotes). (Kalle) . Fixed bug #55415 (php_info produces invalid anchor names). (Kalle, Johannes) . Added ?? operator. (Andrea) + . Added <=> operator. (Andrea) . Added \u{xxxxx} Unicode Codepoint Escape Syntax. (Andrea) . Fixed oversight where define() did not support arrays yet const syntax did. (Andrea, Dmitry) . Use "integer" and "float" instead of "long" and "double" in ZPP, type hint and conversion error messages. (Andrea) diff --git a/UPGRADING b/UPGRADING index a4c9374534c..af84ee94fe0 100644 --- a/UPGRADING +++ b/UPGRADING @@ -398,6 +398,8 @@ Other . Added \u{xxxxxx} Unicode Codepoint Escape Syntax for double-quoted strings and heredocs. . define() now supports arrays as constant values, fixing an oversight where define() did not support arrays yet const syntax did. + . Added the comparison operator (<=>), aka the spaceship operator. + (RFC: https://wiki.php.net/rfc/combined-comparison-operator) ======================================== 3. Changes in SAPI modules From 9fb48edf3c32914330b7a5081a34b4328bf6da68 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 20 Feb 2015 10:31:24 +0300 Subject: [PATCH 03/59] Fixed type mismatch --- ext/opcache/zend_shared_alloc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/opcache/zend_shared_alloc.h b/ext/opcache/zend_shared_alloc.h index 2ca15db86bd..0090dddf8fc 100644 --- a/ext/opcache/zend_shared_alloc.h +++ b/ext/opcache/zend_shared_alloc.h @@ -91,7 +91,7 @@ typedef struct _handler_entry { typedef struct _zend_shared_memory_state { int *positions; /* current positions for each segment */ - int shared_free; /* amount of free shared memory */ + size_t shared_free; /* amount of free shared memory */ } zend_shared_memory_state; typedef struct _zend_smm_shared_globals { From d85113702cc6030a9149f518c55953ccb6933a7c Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 20 Feb 2015 13:28:26 +0300 Subject: [PATCH 04/59] Lazy duplication of op_array->static_variables --- Zend/zend_compile.c | 10 +++++++++- Zend/zend_execute.c | 6 ++++++ Zend/zend_opcode.c | 12 ++++++++---- Zend/zend_types.h | 3 +++ ext/opcache/ZendAccelerator.c | 18 +++++++++++++++--- ext/opcache/zend_accelerator_util_funcs.c | 17 +++++------------ ext/opcache/zend_persist.c | 18 ++++++++++++++++-- ext/opcache/zend_persist_calc.c | 9 +++++++-- ext/reflection/php_reflection.c | 6 ++++++ 9 files changed, 75 insertions(+), 24 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 36055258f6f..67b61831598 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -865,7 +865,9 @@ ZEND_API void function_add_ref(zend_function *function) /* {{{ */ (*op_array->refcount)++; if (op_array->static_variables) { - op_array->static_variables = zend_array_dup(op_array->static_variables); + if (!(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) { + GC_REFCOUNT(op_array->static_variables)++; + } } op_array->run_time_cache = NULL; } else if (function->type == ZEND_INTERNAL_FUNCTION) { @@ -3092,6 +3094,12 @@ static void zend_compile_static_var_common(zend_ast *var_ast, zval *value, zend_ zend_hash_init(CG(active_op_array)->static_variables, 8, NULL, ZVAL_PTR_DTOR, 0); } + if (GC_REFCOUNT(CG(active_op_array)->static_variables) > 1) { + if (!(GC_FLAGS(CG(active_op_array)->static_variables) & IS_ARRAY_IMMUTABLE)) { + GC_REFCOUNT(CG(active_op_array)->static_variables)--; + } + CG(active_op_array)->static_variables = zend_array_dup(CG(active_op_array)->static_variables); + } zend_hash_update(CG(active_op_array)->static_variables, Z_STR(var_node.u.constant), value); opline = zend_emit_op(&result, by_ref ? ZEND_FETCH_W : ZEND_FETCH_R, &var_node, NULL); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 539b1e4dd7c..00a68613fcb 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1166,6 +1166,12 @@ static zend_always_inline HashTable *zend_get_target_symbol_table(zend_execute_d } else if (EXPECTED(fetch_type == ZEND_FETCH_STATIC)) { ZEND_ASSERT(EX(func)->op_array.static_variables != NULL); ht = EX(func)->op_array.static_variables; + if (GC_REFCOUNT(ht) > 1) { + if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) { + GC_REFCOUNT(ht)--; + } + EX(func)->op_array.static_variables = ht = zend_array_dup(ht); + } } else { ZEND_ASSERT(fetch_type == ZEND_FETCH_LOCAL); if (!EX(symbol_table)) { diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index d75cdd0ff3f..999ee659571 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -130,7 +130,8 @@ ZEND_API void zend_function_dtor(zval *zv) ZEND_API void zend_cleanup_op_array_data(zend_op_array *op_array) { - if (op_array->static_variables) { + if (op_array->static_variables && + !(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) { zend_hash_clean(op_array->static_variables); } } @@ -317,9 +318,12 @@ ZEND_API void destroy_op_array(zend_op_array *op_array) zval *end; uint32_t i; - if (op_array->static_variables) { - zend_hash_destroy(op_array->static_variables); - FREE_HASHTABLE(op_array->static_variables); + if (op_array->static_variables && + !(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) { + if (--GC_REFCOUNT(op_array->static_variables) == 0) { + zend_array_destroy(op_array->static_variables); + FREE_HASHTABLE(op_array->static_variables); + } } if (op_array->run_time_cache && !op_array->function_name) { diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 0f6fabd3c4a..33fb78b6b96 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -345,6 +345,9 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) { #define IS_STR_CONSTANT (1<<3) /* constant index */ #define IS_STR_CONSTANT_UNQUALIFIED (1<<4) /* the same as IS_CONSTANT_UNQUALIFIED */ +/* array flags */ +#define IS_ARRAY_IMMUTABLE (1<<1) /* the same as IS_TYPE_IMMUTABLE */ + /* object flags (zval.value->gc.u.flags) */ #define IS_OBJ_APPLY_COUNT 0x07 #define IS_OBJ_DESTRUCTOR_CALLED (1<<3) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 350bd209eb4..62e62e18214 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -1973,7 +1973,11 @@ static int accel_clean_non_persistent_function(zval *zv) return ZEND_HASH_APPLY_STOP; } else { if (function->op_array.static_variables) { - accel_fast_hash_destroy(function->op_array.static_variables); + if (!(GC_FLAGS(function->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) { + if (--GC_REFCOUNT(function->op_array.static_variables) == 0) { + accel_fast_hash_destroy(function->op_array.static_variables); + } + } function->op_array.static_variables = NULL; } return ZEND_HASH_APPLY_REMOVE; @@ -2025,7 +2029,11 @@ static void zend_accel_fast_shutdown(void) break; } else { if (func->op_array.static_variables) { - accel_fast_hash_destroy(func->op_array.static_variables); + if (!(GC_FLAGS(func->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) { + if (--GC_REFCOUNT(func->op_array.static_variables) == 0) { + accel_fast_hash_destroy(func->op_array.static_variables); + } + } } zend_accel_fast_del_bucket(EG(function_table), _idx-1, _p); } @@ -2043,7 +2051,11 @@ static void zend_accel_fast_shutdown(void) ZEND_HASH_FOREACH_PTR(&ce->function_table, func) { if (func->type == ZEND_USER_FUNCTION) { if (func->op_array.static_variables) { - accel_fast_hash_destroy(func->op_array.static_variables); + if (!(GC_FLAGS(func->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) { + if (--GC_REFCOUNT(func->op_array.static_variables) == 0) { + accel_fast_hash_destroy(func->op_array.static_variables); + } + } func->op_array.static_variables = NULL; } } diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index dc717ca768b..d9026047677 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -55,8 +55,11 @@ static void zend_accel_destroy_zend_function(zval *zv) if (function->type == ZEND_USER_FUNCTION) { if (function->op_array.static_variables) { - - FREE_HASHTABLE(function->op_array.static_variables); + if (!(GC_FLAGS(function->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) { + if (--GC_REFCOUNT(function->op_array.static_variables) == 0) { + FREE_HASHTABLE(function->op_array.static_variables); + } + } function->op_array.static_variables = NULL; } } @@ -372,16 +375,6 @@ static zend_always_inline void zend_prepare_function_for_execution(zend_op_array /* protect reference count */ op_array->refcount = &zend_accel_refcount; (*op_array->refcount) = ZEND_PROTECTED_REFCOUNT; - - /* copy statics */ - if (UNEXPECTED(op_array->static_variables)) { - HashTable *shared_statics = op_array->static_variables; - - ALLOC_HASHTABLE(op_array->static_variables); - GC_REFCOUNT(op_array->static_variables) = 1; - GC_TYPE(op_array->static_variables) = IS_ARRAY; - zend_hash_clone_zval(op_array->static_variables, shared_statics, 0); - } } static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class_entry *old_ce, zend_class_entry *ce) diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 5b32baa64b5..634dbda4f54 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -204,6 +204,7 @@ static void zend_persist_zval(zval *z) /* make immutable array */ Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE; GC_REFCOUNT(Z_COUNTED_P(z)) = 2; + GC_FLAGS(Z_COUNTED_P(z)) |= IS_ARRAY_IMMUTABLE; Z_ARRVAL_P(z)->u.flags &= ~HASH_FLAG_APPLY_PROTECTION; } } @@ -258,6 +259,7 @@ static void zend_persist_zval_const(zval *z) /* make immutable array */ Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE; GC_REFCOUNT(Z_COUNTED_P(z)) = 2; + GC_FLAGS(Z_COUNTED_P(z)) |= IS_ARRAY_IMMUTABLE; Z_ARRVAL_P(z)->u.flags &= ~HASH_FLAG_APPLY_PROTECTION; } } @@ -278,6 +280,8 @@ static void zend_persist_zval_const(zval *z) } else { zend_accel_store(Z_AST_P(z), sizeof(zend_ast_ref)); Z_ASTVAL_P(z) = zend_persist_ast(Z_ASTVAL_P(z)); + Z_TYPE_FLAGS_P(z) = IS_TYPE_CONSTANT | IS_TYPE_IMMUTABLE; + GC_REFCOUNT(Z_COUNTED_P(z)) = 2; } break; } @@ -313,8 +317,18 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc } if (op_array->static_variables) { - zend_hash_persist(op_array->static_variables, zend_persist_zval); - zend_accel_store(op_array->static_variables, sizeof(HashTable)); + HashTable *stored = zend_shared_alloc_get_xlat_entry(op_array->static_variables); + + if (stored) { + op_array->static_variables = stored; + } else { + zend_hash_persist(op_array->static_variables, zend_persist_zval_const); + zend_accel_store(op_array->static_variables, sizeof(HashTable)); + /* make immutable array */ + GC_REFCOUNT(op_array->static_variables) = 2; + GC_TYPE_INFO(op_array->static_variables) = IS_ARRAY | (IS_ARRAY_IMMUTABLE << 8); + op_array->static_variables->u.flags &= ~HASH_FLAG_APPLY_PROTECTION; + } } if (zend_shared_alloc_get_xlat_entry(op_array->opcodes)) { diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c index c5523e7d89a..2f211e43cb8 100644 --- a/ext/opcache/zend_persist_calc.c +++ b/ext/opcache/zend_persist_calc.c @@ -150,8 +150,13 @@ static void zend_persist_op_array_calc_ex(zend_op_array *op_array) } if (op_array->static_variables) { - ADD_DUP_SIZE(op_array->static_variables, sizeof(HashTable)); - zend_hash_persist_calc(op_array->static_variables, zend_persist_zval_calc); + if (!zend_shared_alloc_get_xlat_entry(op_array->static_variables)) { + HashTable *old = op_array->static_variables; + + ADD_DUP_SIZE(op_array->static_variables, sizeof(HashTable)); + zend_hash_persist_calc(op_array->static_variables, zend_persist_zval_calc); + zend_shared_alloc_register_xlat_entry(old, op_array->static_variables); + } } if (zend_shared_alloc_get_xlat_entry(op_array->opcodes)) { diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 1f16c4da78b..80e04046ed1 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -1852,6 +1852,12 @@ ZEND_METHOD(reflection_function, getStaticVariables) /* Return an empty array in case no static variables exist */ array_init(return_value); if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.static_variables != NULL) { + if (GC_REFCOUNT(fptr->op_array.static_variables) > 1) { + if (!(GC_FLAGS(fptr->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) { + GC_REFCOUNT(fptr->op_array.static_variables)--; + } + fptr->op_array.static_variables = zend_array_dup(fptr->op_array.static_variables); + } zend_hash_apply_with_argument(fptr->op_array.static_variables, (apply_func_arg_t) zval_update_constant_inline_change, fptr->common.scope); zend_hash_copy(Z_ARRVAL_P(return_value), fptr->op_array.static_variables, zval_add_ref); } From 04836f0e55f7155ce00abfb4a295fd981df9f81e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 20 Feb 2015 13:46:32 +0300 Subject: [PATCH 05/59] Removed dead code --- ext/opcache/zend_accelerator_util_funcs.c | 73 ++++++++--------------- 1 file changed, 25 insertions(+), 48 deletions(-) diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index d9026047677..f3c68246679 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -711,21 +711,14 @@ static void zend_accel_function_hash_copy(HashTable *target, HashTable *source) for (idx = 0; idx < source->nNumUsed; idx++) { p = source->arData + idx; if (Z_TYPE(p->val) == IS_UNDEF) continue; - if (p->key) { - t = zend_hash_add(target, p->key, &p->val); - if (UNEXPECTED(t == NULL)) { - if (p->key->len > 0 && p->key->val[0] == 0) { - /* Mangled key */ - t = zend_hash_update(target, p->key, &p->val); - } else { - t = zend_hash_find(target, p->key); - goto failure; - } - } - } else { - t = zend_hash_index_add(target, p->h, &p->val); - if (UNEXPECTED(t == NULL)) { - t = zend_hash_index_find(target, p->h); + ZEND_ASSERT(p->key); + t = zend_hash_add(target, p->key, &p->val); + if (UNEXPECTED(t == NULL)) { + if (p->key->len > 0 && p->key->val[0] == 0) { + /* Mangled key */ + t = zend_hash_update(target, p->key, &p->val); + } else { + t = zend_hash_find(target, p->key); goto failure; } } @@ -760,21 +753,14 @@ static void zend_accel_function_hash_copy_from_shm(HashTable *target, HashTable for (idx = 0; idx < source->nNumUsed; idx++) { p = source->arData + idx; if (Z_TYPE(p->val) == IS_UNDEF) continue; - if (p->key) { - t = zend_hash_add(target, p->key, &p->val); - if (UNEXPECTED(t == NULL)) { - if (p->key->len > 0 && p->key->val[0] == 0) { - /* Mangled key */ - t = zend_hash_update(target, p->key, &p->val); - } else { - t = zend_hash_find(target, p->key); - goto failure; - } - } - } else { - t = zend_hash_index_add(target, p->h, &p->val); - if (UNEXPECTED(t == NULL)) { - t = zend_hash_index_find(target, p->h); + ZEND_ASSERT(p->key); + t = zend_hash_add(target, p->key, &p->val); + if (UNEXPECTED(t == NULL)) { + if (p->key->len > 0 && p->key->val[0] == 0) { + /* Mangled key */ + t = zend_hash_update(target, p->key, &p->val); + } else { + t = zend_hash_find(target, p->key); goto failure; } } @@ -811,24 +797,15 @@ static void zend_accel_class_hash_copy(HashTable *target, HashTable *source, uni for (idx = 0; idx < source->nNumUsed; idx++) { p = source->arData + idx; if (Z_TYPE(p->val) == IS_UNDEF) continue; - if (p->key) { - t = zend_hash_add(target, p->key, &p->val); - if (UNEXPECTED(t == NULL)) { - if (p->key->len > 0 && p->key->val[0] == 0) { - /* Mangled key - ignore and wait for runtime */ - continue; - } else if (!ZCG(accel_directives).ignore_dups) { - t = zend_hash_find(target, p->key); - goto failure; - } - } - } else { - t = zend_hash_index_add(target, p->h, &p->val); - if (UNEXPECTED(t == NULL)) { - if (!ZCG(accel_directives).ignore_dups) { - t = zend_hash_index_find(target,p->h); - goto failure; - } + ZEND_ASSERT(p->key); + t = zend_hash_add(target, p->key, &p->val); + if (UNEXPECTED(t == NULL)) { + if (p->key->len > 0 && p->key->val[0] == 0) { + /* Mangled key - ignore and wait for runtime */ + continue; + } else if (!ZCG(accel_directives).ignore_dups) { + t = zend_hash_find(target, p->key); + goto failure; } } if (pCopyConstructor) { From 5f76eed14e7981a5e4361364dd0fdd2bf9d531a8 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 20 Feb 2015 14:59:30 +0300 Subject: [PATCH 06/59] don't count op_arrays stored in opcache SHM --- Zend/zend_API.c | 2 +- Zend/zend_builtin_functions.c | 6 ++++-- Zend/zend_closures.c | 4 +++- Zend/zend_compile.c | 8 ++++++-- Zend/zend_generators.c | 4 +++- Zend/zend_opcode.c | 2 +- ext/opcache/zend_accelerator_util_funcs.c | 18 +----------------- ext/opcache/zend_persist.c | 2 +- 8 files changed, 20 insertions(+), 26 deletions(-) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index fe6ae338027..693a8340f8c 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3915,7 +3915,7 @@ ZEND_API zend_string *zend_resolve_method_name(zend_class_entry *ce, zend_functi zend_string *name; if (f->common.type != ZEND_USER_FUNCTION || - *(f->op_array.refcount) < 2 || + (f->op_array.refcount && *(f->op_array.refcount) < 2) || !f->common.scope || !f->common.scope->trait_aliases) { return f->common.function_name; diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index da90e4c98d9..035a4c6c886 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1227,7 +1227,7 @@ ZEND_FUNCTION(get_class_methods) zend_binary_strcasecmp(key->val, key->len, mptr->common.function_name->val, len) == 0) { if (mptr->type == ZEND_USER_FUNCTION && - *mptr->op_array.refcount > 1 && + (!mptr->op_array.refcount || *mptr->op_array.refcount > 1) && !same_name(key, mptr->common.function_name)) { ZVAL_STR_COPY(&method_name, zend_find_alias_name(mptr->common.scope, key)); zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &method_name); @@ -1936,7 +1936,9 @@ ZEND_FUNCTION(create_function) zend_error(E_ERROR, "Unexpected inconsistency in create_function()"); RETURN_FALSE; } - (*func->refcount)++; + if (func->refcount) { + (*func->refcount)++; + } static_variables = func->static_variables; func->static_variables = NULL; zend_hash_str_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME)-1); diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index fb37bf2705a..967cb6acc62 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -499,7 +499,9 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent zend_hash_apply_with_arguments(static_variables, zval_copy_static_var, 1, closure->func.op_array.static_variables); } closure->func.op_array.run_time_cache = NULL; - (*closure->func.op_array.refcount)++; + if (closure->func.op_array.refcount) { + (*closure->func.op_array.refcount)++; + } } else { /* verify that we aren't binding internal function to a wrong scope */ if(func->common.scope != NULL) { diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 67b61831598..2608cf150a4 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -863,7 +863,9 @@ ZEND_API void function_add_ref(zend_function *function) /* {{{ */ if (function->type == ZEND_USER_FUNCTION) { zend_op_array *op_array = &function->op_array; - (*op_array->refcount)++; + if (op_array->refcount) { + (*op_array->refcount)++; + } if (op_array->static_variables) { if (!(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) { GC_REFCOUNT(op_array->static_variables)++; @@ -910,7 +912,9 @@ ZEND_API int do_bind_function(const zend_op_array *op_array, const zend_op *opli } return FAILURE; } else { - (*function->op_array.refcount)++; + if (function->op_array.refcount) { + (*function->op_array.refcount)++; + } function->op_array.static_variables = NULL; /* NULL out the unbound function */ return SUCCESS; } diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index 971d4e7bc8c..a8c589964b5 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -236,7 +236,9 @@ ZEND_API void zend_generator_create_zval(zend_execute_data *call, zend_op_array zend_op_array *op_array_copy = (zend_op_array*)emalloc(sizeof(zend_op_array)); *op_array_copy = *op_array; - (*op_array->refcount)++; + if (op_array->refcount) { + (*op_array->refcount)++; + } op_array->run_time_cache = NULL; if (op_array->static_variables) { ALLOC_HASHTABLE(op_array_copy->static_variables); diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 999ee659571..9e79697589c 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -330,7 +330,7 @@ ZEND_API void destroy_op_array(zend_op_array *op_array) efree(op_array->run_time_cache); } - if (--(*op_array->refcount)>0) { + if (!op_array->refcount || --(*op_array->refcount)>0) { return; } diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index f3c68246679..afe3c4e421a 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -25,10 +25,6 @@ #include "zend_persist.h" #include "zend_shared_alloc.h" -#define ZEND_PROTECTED_REFCOUNT (1<<30) - -static uint32_t zend_accel_refcount = ZEND_PROTECTED_REFCOUNT; - #if SIZEOF_SIZE_T <= SIZEOF_ZEND_LONG /* If sizeof(void*) == sizeof(ulong) we can use zend_hash index functions */ # define accel_xlat_set(old, new) zend_hash_index_update_ptr(&ZCG(bind_hash), (zend_ulong)(zend_uintptr_t)(old), (new)) @@ -369,14 +365,6 @@ static void zend_hash_clone_zval(HashTable *ht, HashTable *source, int bind) } } -/* protects reference count, creates copy of statics */ -static zend_always_inline void zend_prepare_function_for_execution(zend_op_array *op_array) -{ - /* protect reference count */ - op_array->refcount = &zend_accel_refcount; - (*op_array->refcount) = ZEND_PROTECTED_REFCOUNT; -} - static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class_entry *old_ce, zend_class_entry *ce) { uint idx; @@ -429,10 +417,9 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class /* we use refcount to show that op_array is referenced from several places */ if (new_entry->refcount != NULL) { accel_xlat_set(Z_PTR(p->val), new_entry); + new_entry->refcount = NULL; } - zend_prepare_function_for_execution(new_entry); - if (old_ce == new_entry->scope) { new_entry->scope = ce; } else { @@ -765,7 +752,6 @@ static void zend_accel_function_hash_copy_from_shm(HashTable *target, HashTable } } Z_PTR_P(t) = ARENA_REALLOC(Z_PTR(p->val)); - zend_prepare_function_for_execution((zend_op_array*)Z_PTR_P(t)); } target->nInternalPointer = target->nNumOfElements ? 0 : INVALID_IDX; return; @@ -850,8 +836,6 @@ zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, zend_accel_function_hash_copy_from_shm(CG(function_table), &persistent_script->function_table); } - zend_prepare_function_for_execution(op_array); - /* Register __COMPILER_HALT_OFFSET__ constant */ if (persistent_script->compiler_halt_offset != 0 && persistent_script->full_path) { diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 634dbda4f54..5fb5ab2d36d 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -297,7 +297,7 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc return; } - if (--(*op_array->refcount) == 0) { + if (op_array->refcount && --(*op_array->refcount) == 0) { efree(op_array->refcount); } op_array->refcount = NULL; From e6819794eb9c43367f77f8c4e6a95afac669adbf Mon Sep 17 00:00:00 2001 From: Mariano Iglesias Date: Thu, 19 Feb 2015 12:46:00 -0300 Subject: [PATCH 07/59] Adding 'v' formatting to DateTime::format(), and adding constant DateTime::RFC3339_EXTENDED to output datetime using the RFC3339 extended format (aka ISO8601 extended format) --- ext/date/php_date.c | 39 +++++++++++++------ ext/date/tests/DateTime_verify.phpt | 4 +- .../tests/rfc-datetime_rfc3339_extended.phpt | 17 ++++++++ 3 files changed, 47 insertions(+), 13 deletions(-) create mode 100644 ext/date/tests/rfc-datetime_rfc3339_extended.phpt diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 819b1732f36..4b6deaf6488 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -809,6 +809,16 @@ PHP_RSHUTDOWN_FUNCTION(date) #define DATE_FORMAT_ISO8601 "Y-m-d\\TH:i:sO" +/* + * RFC3339, Appendix A: http://www.ietf.org/rfc/rfc3339.txt + * ISO 8601 also requires (in section 5.3.1.3) that a decimal fraction + * be proceeded by a "0" if less than unity. Annex B.2 of ISO 8601 + * gives examples where the decimal fractions are not preceded by a "0". + * This grammar assumes section 5.3.1.3 is correct and that Annex B.2 is + * in error. + */ +#define DATE_FORMAT_RFC3339_EXTENDED "Y-m-d\\TH:i:s.vP" + /* * This comes from various sources that like to contradict. I'm going with the * format here because of: @@ -849,12 +859,15 @@ PHP_MINIT_FUNCTION(date) */ REGISTER_STRING_CONSTANT("DATE_COOKIE", DATE_FORMAT_COOKIE, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("DATE_ISO8601", DATE_FORMAT_ISO8601, CONST_CS | CONST_PERSISTENT); + REGISTER_STRING_CONSTANT("DATE_RFC822", DATE_FORMAT_RFC822, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("DATE_RFC850", DATE_FORMAT_RFC850, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("DATE_RFC1036", DATE_FORMAT_RFC1036, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("DATE_RFC1123", DATE_FORMAT_RFC1123, CONST_CS | CONST_PERSISTENT); REGISTER_STRING_CONSTANT("DATE_RFC2822", DATE_FORMAT_RFC2822, CONST_CS | CONST_PERSISTENT); - REGISTER_STRING_CONSTANT("DATE_RFC3339", DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT); + REGISTER_STRING_CONSTANT("DATE_RFC3339", DATE_FORMAT_RFC3339, CONST_CS | CONST_PERSISTENT); + REGISTER_STRING_CONSTANT("DATE_RFC3339_EXTENDED", DATE_FORMAT_RFC3339_EXTENDED, CONST_CS | CONST_PERSISTENT); + /* * RSS 2.0 Specification: http://blogs.law.harvard.edu/tech/rss * "All date-times in RSS conform to the Date and Time Specification of RFC 822, @@ -1145,6 +1158,7 @@ static zend_string *date_format(char *format, size_t format_len, timelib_time *t case 'i': length = slprintf(buffer, 32, "%02d", (int) t->i); break; case 's': length = slprintf(buffer, 32, "%02d", (int) t->s); break; case 'u': length = slprintf(buffer, 32, "%06d", (int) floor(t->f * 1000000 + 0.5)); break; + case 'v': length = slprintf(buffer, 32, "%03d", (int) floor(t->f * 1000 + 0.5)); break; /* timezone */ case 'I': length = slprintf(buffer, 32, "%d", localtime ? offset->is_dst : 0); break; @@ -1981,17 +1995,18 @@ static void date_register_classes(void) /* {{{ */ #define REGISTER_DATE_CLASS_CONST_STRING(const_name, value) \ zend_declare_class_constant_stringl(date_ce_date, const_name, sizeof(const_name)-1, value, sizeof(value)-1); - REGISTER_DATE_CLASS_CONST_STRING("ATOM", DATE_FORMAT_RFC3339); - REGISTER_DATE_CLASS_CONST_STRING("COOKIE", DATE_FORMAT_COOKIE); - REGISTER_DATE_CLASS_CONST_STRING("ISO8601", DATE_FORMAT_ISO8601); - REGISTER_DATE_CLASS_CONST_STRING("RFC822", DATE_FORMAT_RFC822); - REGISTER_DATE_CLASS_CONST_STRING("RFC850", DATE_FORMAT_RFC850); - REGISTER_DATE_CLASS_CONST_STRING("RFC1036", DATE_FORMAT_RFC1036); - REGISTER_DATE_CLASS_CONST_STRING("RFC1123", DATE_FORMAT_RFC1123); - REGISTER_DATE_CLASS_CONST_STRING("RFC2822", DATE_FORMAT_RFC2822); - REGISTER_DATE_CLASS_CONST_STRING("RFC3339", DATE_FORMAT_RFC3339); - REGISTER_DATE_CLASS_CONST_STRING("RSS", DATE_FORMAT_RFC1123); - REGISTER_DATE_CLASS_CONST_STRING("W3C", DATE_FORMAT_RFC3339); + REGISTER_DATE_CLASS_CONST_STRING("ATOM", DATE_FORMAT_RFC3339); + REGISTER_DATE_CLASS_CONST_STRING("COOKIE", DATE_FORMAT_COOKIE); + REGISTER_DATE_CLASS_CONST_STRING("ISO8601", DATE_FORMAT_ISO8601); + REGISTER_DATE_CLASS_CONST_STRING("RFC822", DATE_FORMAT_RFC822); + REGISTER_DATE_CLASS_CONST_STRING("RFC850", DATE_FORMAT_RFC850); + REGISTER_DATE_CLASS_CONST_STRING("RFC1036", DATE_FORMAT_RFC1036); + REGISTER_DATE_CLASS_CONST_STRING("RFC1123", DATE_FORMAT_RFC1123); + REGISTER_DATE_CLASS_CONST_STRING("RFC2822", DATE_FORMAT_RFC2822); + REGISTER_DATE_CLASS_CONST_STRING("RFC3339", DATE_FORMAT_RFC3339); + REGISTER_DATE_CLASS_CONST_STRING("RFC3339_EXTENDED", DATE_FORMAT_RFC3339_EXTENDED); + REGISTER_DATE_CLASS_CONST_STRING("RSS", DATE_FORMAT_RFC1123); + REGISTER_DATE_CLASS_CONST_STRING("W3C", DATE_FORMAT_RFC3339); INIT_CLASS_ENTRY(ce_immutable, "DateTimeImmutable", date_funcs_immutable); ce_immutable.create_object = date_object_new_date; diff --git a/ext/date/tests/DateTime_verify.phpt b/ext/date/tests/DateTime_verify.phpt index 95aa37a5261..33768969dc1 100644 --- a/ext/date/tests/DateTime_verify.phpt +++ b/ext/date/tests/DateTime_verify.phpt @@ -156,7 +156,7 @@ array(18) { } } ..and get names of all its class constants -array(11) { +array(12) { ["ATOM"]=> string(13) "Y-m-d\TH:i:sP" ["COOKIE"]=> @@ -175,6 +175,8 @@ array(11) { string(16) "D, d M Y H:i:s O" ["RFC3339"]=> string(13) "Y-m-d\TH:i:sP" + ["RFC3339_EXTENDED"]=> + string(15) "Y-m-d\TH:i:s.vP" ["RSS"]=> string(16) "D, d M Y H:i:s O" ["W3C"]=> diff --git a/ext/date/tests/rfc-datetime_rfc3339_extended.phpt b/ext/date/tests/rfc-datetime_rfc3339_extended.phpt new file mode 100644 index 00000000000..5235aa666b8 --- /dev/null +++ b/ext/date/tests/rfc-datetime_rfc3339_extended.phpt @@ -0,0 +1,17 @@ +--TEST-- +RFC: DateTime RFC3339 Extended +--CREDITS-- +Mariano Iglesias +--FILE-- +format(DateTime::RFC3339_EXTENDED)); +var_dump($date->format('u')); +var_dump($date->format('v')); +--EXPECT-- +string(29) "2009-09-28T09:45:31.918-03:00" +string(6) "918312" +string(3) "918" From 5100afb7dd06b2515a3c524b4be02c8d3a80a091 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 20 Feb 2015 15:38:06 +0300 Subject: [PATCH 08/59] Simplify reallocation during copying data from SHM to process memory --- ext/opcache/zend_accelerator_util_funcs.c | 48 +++-------------------- ext/opcache/zend_persist.c | 18 --------- 2 files changed, 5 insertions(+), 61 deletions(-) diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index afe3c4e421a..8a52a531034 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -413,30 +413,11 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class ZVAL_PTR(&q->val, ARENA_REALLOC(Z_PTR(p->val))); new_entry = (zend_op_array*)Z_PTR(q->val); - /* Copy constructor */ - /* we use refcount to show that op_array is referenced from several places */ - if (new_entry->refcount != NULL) { - accel_xlat_set(Z_PTR(p->val), new_entry); - new_entry->refcount = NULL; - } - - if (old_ce == new_entry->scope) { - new_entry->scope = ce; - } else { - if ((new_ce = accel_xlat_get(new_entry->scope)) != NULL) { - new_entry->scope = new_ce; - } else { - zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name->val, new_entry->function_name->val); - } - } + new_entry->scope = ARENA_REALLOC(new_entry->scope); /* update prototype */ if (new_entry->prototype) { - if ((new_prototype = accel_xlat_get(new_entry->prototype)) != NULL) { - new_entry->prototype = new_prototype; - } else { - zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s, function %s", ce->name->val, new_entry->function_name->val); - } + new_entry->prototype = ARENA_REALLOC(new_entry->prototype); } } } @@ -497,24 +478,14 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla prop_info->doc_comment = NULL; } } - if (prop_info->ce == old_ce) { - prop_info->ce = ce; - } else if ((new_ce = accel_xlat_get(prop_info->ce)) != NULL) { - prop_info->ce = new_ce; - } else { - zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s, property %s", ce->name->val, prop_info->name->val); - } + prop_info->ce = ARENA_REALLOC(prop_info->ce); } } #define zend_update_inherited_handler(handler) \ { \ if (ce->handler != NULL) { \ - if ((new_func = accel_xlat_get(ce->handler)) != NULL) { \ - ce->handler = new_func; \ - } else { \ - zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME " class loading error, class %s", ce->name->val); \ - } \ + ce->handler = ARENA_REALLOC(ce->handler); \ } \ } @@ -529,11 +500,6 @@ static void zend_class_copy_ctor(zend_class_entry **pce) *pce = ce = ARENA_REALLOC(old_ce); ce->refcount = 1; - if (old_ce->refcount != 1) { - /* this class is not used as a parent for any other classes */ - accel_xlat_set(old_ce, ce); - } - if (old_ce->default_properties_table) { int i; @@ -583,11 +549,7 @@ static void zend_class_copy_ctor(zend_class_entry **pce) } if (ce->parent) { - if ((new_ce = accel_xlat_get(ce->parent)) != NULL) { - ce->parent = new_ce; - } else { - zend_error(E_ERROR, ACCELERATOR_PRODUCT_NAME" class loading error, class %s", ce->name->val); - } + ce->parent = ARENA_REALLOC(ce->parent); } zend_update_inherited_handler(constructor); diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 5fb5ab2d36d..1c440eceae0 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -508,8 +508,6 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc if (op_array->scope && op_array->prototype) { if ((persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->prototype))) { op_array->prototype = (union _zend_function*)persist_ptr; - /* we use refcount to show that op_array is referenced from several places */ - op_array->prototype->op_array.refcount++; } } else { op_array->prototype = NULL; @@ -674,63 +672,47 @@ static int zend_update_parent_ce(zval *zv) if (ce->parent) { ce->parent = zend_shared_alloc_get_xlat_entry(ce->parent); - /* We use refcount to show if the class is used as a parent */ - ce->parent->refcount++; } /* update methods */ if (ce->constructor) { ce->constructor = zend_shared_alloc_get_xlat_entry(ce->constructor); - /* we use refcount to show that op_array is referenced from several places */ - ce->constructor->op_array.refcount++; } if (ce->destructor) { ce->destructor = zend_shared_alloc_get_xlat_entry(ce->destructor); - ce->destructor->op_array.refcount++; } if (ce->clone) { ce->clone = zend_shared_alloc_get_xlat_entry(ce->clone); - ce->clone->op_array.refcount++; } if (ce->__get) { ce->__get = zend_shared_alloc_get_xlat_entry(ce->__get); - ce->__get->op_array.refcount++; } if (ce->__set) { ce->__set = zend_shared_alloc_get_xlat_entry(ce->__set); - ce->__set->op_array.refcount++; } if (ce->__call) { ce->__call = zend_shared_alloc_get_xlat_entry(ce->__call); - ce->__call->op_array.refcount++; } if (ce->serialize_func) { ce->serialize_func = zend_shared_alloc_get_xlat_entry(ce->serialize_func); - ce->serialize_func->op_array.refcount++; } if (ce->unserialize_func) { ce->unserialize_func = zend_shared_alloc_get_xlat_entry(ce->unserialize_func); - ce->unserialize_func->op_array.refcount++; } if (ce->__isset) { ce->__isset = zend_shared_alloc_get_xlat_entry(ce->__isset); - ce->__isset->op_array.refcount++; } if (ce->__unset) { ce->__unset = zend_shared_alloc_get_xlat_entry(ce->__unset); - ce->__unset->op_array.refcount++; } if (ce->__tostring) { ce->__tostring = zend_shared_alloc_get_xlat_entry(ce->__tostring); - ce->__tostring->op_array.refcount++; } if (ce->__callstatic) { ce->__callstatic = zend_shared_alloc_get_xlat_entry(ce->__callstatic); - ce->__callstatic->op_array.refcount++; } if (ce->__debugInfo) { ce->__debugInfo = zend_shared_alloc_get_xlat_entry(ce->__debugInfo); - ce->__debugInfo->op_array.refcount++; } zend_hash_apply(&ce->properties_info, (apply_func_t) zend_update_property_info_ce); return 0; From 623810eff40d82e6d7c9f17aeaacec43d741d4c6 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 20 Feb 2015 16:08:57 +0300 Subject: [PATCH 09/59] Use fast SSE2 memcpy() for copying block of data from SHM to process memory --- ext/opcache/ZendAccelerator.c | 6 ++++ ext/opcache/zend_accelerator_util_funcs.c | 35 +++++++++++++++++++++++ ext/opcache/zend_persist.c | 5 ++++ ext/opcache/zend_persist_calc.c | 10 +++++++ 4 files changed, 56 insertions(+) diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index 62e62e18214..cdcbfeda560 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -1163,7 +1163,13 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr memory_used = zend_accel_script_persist_calc(new_persistent_script, key, key_length); /* Allocate shared memory */ +#ifdef __SSE2__ + /* Align to 64-byte boundary */ + ZCG(mem) = zend_shared_alloc(memory_used + 64); + ZCG(mem) = (void*)(((zend_uintptr_t)ZCG(mem) + 63L) & ~63L); +#else ZCG(mem) = zend_shared_alloc(memory_used); +#endif if (!ZCG(mem)) { zend_accel_schedule_restart_if_necessary(ACCEL_RESTART_OOM); zend_shared_alloc_unlock(); diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index 8a52a531034..2e7f0c8da5a 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -771,6 +771,34 @@ failure: zend_error(E_ERROR, "Cannot redeclare class %s", ce1->name->val); } +#ifdef __SSE2__ +#include +#include + +static zend_always_inline void fast_memcpy(void *dest, const void *src, size_t size) +{ + __m128i *dqdest = (__m128i*)dest; + const __m128i *dqsrc = (const __m128i*)src; + const __m128i *end = (const __m128i*)((const char*)src + size); + + do { + _mm_prefetch(dqsrc + 4, _MM_HINT_NTA); + _mm_prefetch(dqsrc + 6, _MM_HINT_NTA); + + __m128i xmm0 = _mm_load_si128(dqsrc + 0); + __m128i xmm1 = _mm_load_si128(dqsrc + 1); + __m128i xmm2 = _mm_load_si128(dqsrc + 2); + __m128i xmm3 = _mm_load_si128(dqsrc + 3); + dqsrc += 4; + _mm_stream_si128(dqdest + 0, xmm0); + _mm_stream_si128(dqdest + 1, xmm1); + _mm_stream_si128(dqdest + 2, xmm2); + _mm_stream_si128(dqdest + 3, xmm3); + dqdest += 4; + } while (dqsrc != end); +} +#endif + zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, int from_shared_memory) { zend_op_array *op_array; @@ -784,8 +812,15 @@ zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script, ZCG(current_persistent_script) = persistent_script; ZCG(arena_mem) = NULL; if (EXPECTED(persistent_script->arena_size)) { +#ifdef __SSE2__ + /* Target address must be aligned to 64-byte boundary */ + ZCG(arena_mem) = zend_arena_alloc(&CG(arena), persistent_script->arena_size + 64); + ZCG(arena_mem) = (void*)(((zend_uintptr_t)ZCG(arena_mem) + 63L) & ~63L); + fast_memcpy(ZCG(arena_mem), persistent_script->arena_mem, persistent_script->arena_size); +#else ZCG(arena_mem) = zend_arena_alloc(&CG(arena), persistent_script->arena_size); memcpy(ZCG(arena_mem), persistent_script->arena_mem, persistent_script->arena_size); +#endif } /* Copy all the necessary stuff from shared memory to regular memory, and protect the shared script */ diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index 1c440eceae0..eb442e97428 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -734,6 +734,11 @@ zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script *key = zend_accel_memdup(*key, key_length + 1); zend_accel_store_string(script->full_path); +#ifdef __SSE2__ + /* Align to 64-byte boundary */ + ZCG(mem) = (void*)(((zend_uintptr_t)ZCG(mem) + 63L) & ~63L); +#endif + script->arena_mem = ZCG(arena_mem) = ZCG(mem); ZCG(mem) = (void*)((char*)ZCG(mem) + script->arena_size); diff --git a/ext/opcache/zend_persist_calc.c b/ext/opcache/zend_persist_calc.c index 2f211e43cb8..7d77d62b8dc 100644 --- a/ext/opcache/zend_persist_calc.c +++ b/ext/opcache/zend_persist_calc.c @@ -361,10 +361,20 @@ uint zend_accel_script_persist_calc(zend_persistent_script *new_persistent_scrip ADD_DUP_SIZE(key, key_length + 1); ADD_STRING(new_persistent_script->full_path); +#ifdef __SSE2__ + /* Align size to 64-byte boundary */ + new_persistent_script->size = (new_persistent_script->size + 63) & ~63; +#endif + zend_accel_persist_class_table_calc(&new_persistent_script->class_table); zend_hash_persist_calc(&new_persistent_script->function_table, zend_persist_op_array_calc); zend_persist_op_array_calc_ex(&new_persistent_script->main_op_array); +#ifdef __SSE2__ + /* Align size to 64-byte boundary */ + new_persistent_script->arena_size = (new_persistent_script->arena_size + 63) & ~63; +#endif + new_persistent_script->size += new_persistent_script->arena_size; ZCG(current_persistent_script) = NULL; From c111d1cd701d2720fdf2707640e70cc9ec5cf76e Mon Sep 17 00:00:00 2001 From: Julien Pauli Date: Fri, 20 Feb 2015 15:09:35 +0100 Subject: [PATCH 10/59] fix #68557 --- ext/spl/spl_directory.c | 11 +++++++---- ext/spl/tests/bug68557.phpt | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 ext/spl/tests/bug68557.phpt diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 7fc65cc791c..34f0415b533 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -202,18 +202,21 @@ static inline void spl_filesystem_object_get_file_name(spl_filesystem_object *in { char slash = SPL_HAS_FLAG(intern->flags, SPL_FILE_DIR_UNIXPATHS) ? '/' : DEFAULT_SLASH; - if (!intern->file_name) { - switch (intern->type) { + switch (intern->type) { case SPL_FS_INFO: case SPL_FS_FILE: - php_error_docref(NULL TSRMLS_CC, E_ERROR, "Object not initialized"); + if (!intern->file_name) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Object not initialized"); + } break; case SPL_FS_DIR: + if (intern->file_name) { + efree(intern->file_name); + } intern->file_name_len = spprintf(&intern->file_name, 0, "%s%c%s", spl_filesystem_object_get_path(intern, NULL TSRMLS_CC), slash, intern->u.dir.entry.d_name); break; - } } } /* }}} */ diff --git a/ext/spl/tests/bug68557.phpt b/ext/spl/tests/bug68557.phpt new file mode 100644 index 00000000000..bcf66c9d248 --- /dev/null +++ b/ext/spl/tests/bug68557.phpt @@ -0,0 +1,37 @@ +--TEST-- +Bug #68557 (SplFileInfo::getPathname() may be broken) +--FILE-- +seek(0); +var_dump($d->current()->getPathname()); + +$d->seek(1); +var_dump($d->current()->getPathname()); + +$d->seek(0); +var_dump($d->current()->getPathname()); + +$d->seek(1); +var_dump($d->current()->getPathname()); + +$d->seek(2); +var_dump($d->current()->getPathname()); +?> +--CLEAN-- + +--EXPECTF-- +string(%d) "%s/tmp/b" +string(%d) "%s/tmp/a" +string(%d) "%s/tmp/b" +string(%d) "%s/tmp/a" +string(%d) "%s/tmp/.." \ No newline at end of file From b97a9a80980e6ba15998a1286469f088fcc392f0 Mon Sep 17 00:00:00 2001 From: Sobak Date: Fri, 13 Feb 2015 07:17:15 +0100 Subject: [PATCH 11/59] Drop ZE1-compat leftover --- win32/EngineSelect.bat | 5 ----- 1 file changed, 5 deletions(-) delete mode 100755 win32/EngineSelect.bat diff --git a/win32/EngineSelect.bat b/win32/EngineSelect.bat deleted file mode 100755 index 0785bd12fcc..00000000000 --- a/win32/EngineSelect.bat +++ /dev/null @@ -1,5 +0,0 @@ -@if exist ..\ZendEngine2\OBJECTS2_HOWTO ( -move ..\Zend ..\ZendEngine1 -move ..\ZendEngine2 ..\Zend -echo "PLEASE RESTART VISUAL C++ TO RELOAD THE ZEND PROJECT." -exit 1 ) From 6393556a5d17a163dd8bbc85ea3a661b3112cfd6 Mon Sep 17 00:00:00 2001 From: Julien Pauli Date: Fri, 20 Feb 2015 15:43:38 +0100 Subject: [PATCH 12/59] Updated NEWS --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index c2243451853..a0900f0d04f 100644 --- a/NEWS +++ b/NEWS @@ -28,6 +28,10 @@ PHP NEWS . Fixed bug #69054 (Null dereference in readline_(read|write)_history() without parameters). (Laruence) +- SPL: + . Fixed bug #68557 (RecursiveDirectoryIterator::seek(0) broken after + calling getChildren()). (Julien) + - CGI: . Fixed bug #69015 (php-cgi's getopt does not see $argv). (Laruence) From 95be012dcec003752bc43b3d8ed7ff7c3c0c4f85 Mon Sep 17 00:00:00 2001 From: Julien Pauli Date: Fri, 20 Feb 2015 15:44:18 +0100 Subject: [PATCH 13/59] Updated NEWS --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index 9472ff7a9b8..7c80bfaecd2 100644 --- a/NEWS +++ b/NEWS @@ -27,6 +27,10 @@ . Fixed bug #69054 (Null dereference in readline_(read|write)_history() without parameters). (Laruence) +- SPL: + . Fixed bug #68557 (RecursiveDirectoryIterator::seek(0) broken after + calling getChildren()). (Julien) + 19 Feb 2015, PHP 5.6.6 - Core: From 3082177beebdf148b5b4165f5efbc2c26fd0c01b Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Fri, 20 Feb 2015 16:01:34 +0100 Subject: [PATCH 14/59] split test for bug #68557 for windows --- ext/spl/tests/bug68557-win32.phpt | 44 +++++++++++++++++++++++++++++++ ext/spl/tests/bug68557.phpt | 9 ++++++- 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 ext/spl/tests/bug68557-win32.phpt diff --git a/ext/spl/tests/bug68557-win32.phpt b/ext/spl/tests/bug68557-win32.phpt new file mode 100644 index 00000000000..95502a53e8e --- /dev/null +++ b/ext/spl/tests/bug68557-win32.phpt @@ -0,0 +1,44 @@ +--TEST-- +Bug #68557 (SplFileInfo::getPathname() may be broken) +--SKIPIF-- + +--FILE-- +seek(0); +var_dump($d->current()->getPathname()); + +$d->seek(1); +var_dump($d->current()->getPathname()); + +$d->seek(0); +var_dump($d->current()->getPathname()); + +$d->seek(1); +var_dump($d->current()->getPathname()); + +$d->seek(2); +var_dump($d->current()->getPathname()); +?> +--CLEAN-- + +--EXPECTF-- +string(%d) "%s\tmp\." +string(%d) "%s\tmp\.." +string(%d) "%s\tmp\." +string(%d) "%s\tmp\.." +string(%d) "%s\tmp\a" + diff --git a/ext/spl/tests/bug68557.phpt b/ext/spl/tests/bug68557.phpt index bcf66c9d248..c862bda7cf6 100644 --- a/ext/spl/tests/bug68557.phpt +++ b/ext/spl/tests/bug68557.phpt @@ -1,5 +1,11 @@ --TEST-- Bug #68557 (SplFileInfo::getPathname() may be broken) +--SKIPIF-- + --FILE-- Date: Fri, 20 Feb 2015 11:43:18 -0500 Subject: [PATCH 15/59] Fix declare error behavior so that improper usages will actually error --- Zend/tests/bug69092.2.phpt | 18 +++++++++++++++++ Zend/tests/bug69092.phpt | 22 +++++++++++++++++++++ Zend/zend_compile.c | 24 ++++++++++++++++------- ext/mbstring/tests/zend_multibyte-10.phpt | 2 +- ext/mbstring/tests/zend_multibyte-11.phpt | 2 +- ext/mbstring/tests/zend_multibyte-15.phpt | 16 +++++++++++++++ ext/mbstring/tests/zend_multibyte-16.phpt | 14 +++++++++++++ 7 files changed, 89 insertions(+), 9 deletions(-) create mode 100644 Zend/tests/bug69092.2.phpt create mode 100644 Zend/tests/bug69092.phpt create mode 100644 ext/mbstring/tests/zend_multibyte-15.phpt create mode 100644 ext/mbstring/tests/zend_multibyte-16.phpt diff --git a/Zend/tests/bug69092.2.phpt b/Zend/tests/bug69092.2.phpt new file mode 100644 index 00000000000..b3f4bff1752 --- /dev/null +++ b/Zend/tests/bug69092.2.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #69092-2 (Declare Encoding Compile Check Wrong) - multibyte off +--INI-- +zend.multibyte=0 +--FILE-- + +--EXPECTF-- +Warning: declare(encoding=...) ignored because Zend multibyte feature is turned off by settings in %s on line %d + +Fatal error: Encoding declaration pragma must be the very first statement in the script in %s on line %d \ No newline at end of file diff --git a/Zend/tests/bug69092.phpt b/Zend/tests/bug69092.phpt new file mode 100644 index 00000000000..1963d7be02e --- /dev/null +++ b/Zend/tests/bug69092.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #69092 (Declare Encoding Compile Check Wrong) +--SKIPIF-- + +--INI-- +zend.multibyte=On +--FILE-- + +--EXPECTF-- +Fatal error: Encoding declaration pragma must be the very first statement in the script in %s on line %d \ No newline at end of file diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 2608cf150a4..c5479af516c 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3806,14 +3806,24 @@ void zend_compile_declare(zend_ast *ast) /* {{{ */ } else if (zend_string_equals_literal_ci(name, "encoding")) { /* Encoding declaration was already handled during parsing. Here we * only check that it is the first statement in the file. */ - uint32_t num = CG(active_op_array)->last; - while (num > 0 && - (CG(active_op_array)->opcodes[num-1].opcode == ZEND_EXT_STMT || - CG(active_op_array)->opcodes[num-1].opcode == ZEND_TICKS)) { - --num; - } + zend_ast_list *file_ast = zend_ast_get_list(CG(ast)); + + size_t i = 0; + signed char valid = 0; - if (num > 0) { + /* Check to see if this declare is preceeded only by declare statements */ + while (valid == 0 && i < file_ast->children) { + if (file_ast->child[i] == ast) { + valid = 1; + } else if (file_ast->child[i] == NULL) { + valid = -1; + } else if (file_ast->child[i]->kind != ZEND_AST_DECLARE) { + /* declares can only be preceeded by other declares */ + valid = -1; + } + i++; + } + if (valid != 1) { zend_error_noreturn(E_COMPILE_ERROR, "Encoding declaration pragma must be " "the very first statement in the script"); } diff --git a/ext/mbstring/tests/zend_multibyte-10.phpt b/ext/mbstring/tests/zend_multibyte-10.phpt index 138b4899fea..ef8ce9d0bcb 100644 --- a/ext/mbstring/tests/zend_multibyte-10.phpt +++ b/ext/mbstring/tests/zend_multibyte-10.phpt @@ -9,4 +9,4 @@ declare(encoding="ISO-8859-1"); echo "ok\n"; ?> --EXPECTF-- -ok +ok \ No newline at end of file diff --git a/ext/mbstring/tests/zend_multibyte-11.phpt b/ext/mbstring/tests/zend_multibyte-11.phpt index 6844d06370f..0f9874b538d 100644 --- a/ext/mbstring/tests/zend_multibyte-11.phpt +++ b/ext/mbstring/tests/zend_multibyte-11.phpt @@ -10,4 +10,4 @@ declare(encoding="ISO-8859-15") { } ?> --EXPECTF-- -ok +Fatal error: Encoding declaration pragma must be the very first statement in the script in %s on line %d \ No newline at end of file diff --git a/ext/mbstring/tests/zend_multibyte-15.phpt b/ext/mbstring/tests/zend_multibyte-15.phpt new file mode 100644 index 00000000000..6995444bbb2 --- /dev/null +++ b/ext/mbstring/tests/zend_multibyte-15.phpt @@ -0,0 +1,16 @@ +--TEST-- +zend multibyte (15) +--INI-- +zend.multibyte=1 +--FILE-- + +--EXPECTF-- +ok +ok \ No newline at end of file diff --git a/ext/mbstring/tests/zend_multibyte-16.phpt b/ext/mbstring/tests/zend_multibyte-16.phpt new file mode 100644 index 00000000000..4470e3a87f9 --- /dev/null +++ b/ext/mbstring/tests/zend_multibyte-16.phpt @@ -0,0 +1,14 @@ +--TEST-- +zend multibyte (16) +--INI-- +zend.multibyte=1 +--FILE-- + +--EXPECTF-- +ok +ok \ No newline at end of file From b3be3c5b17e4da1ecfecdb608cce7ceeb176fc43 Mon Sep 17 00:00:00 2001 From: Anthony Ferrara Date: Fri, 20 Feb 2015 11:54:33 -0500 Subject: [PATCH 16/59] Clean up tri-state logic to use break instead --- Zend/zend_compile.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index c5479af516c..dae13483eb3 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3809,17 +3809,18 @@ void zend_compile_declare(zend_ast *ast) /* {{{ */ zend_ast_list *file_ast = zend_ast_get_list(CG(ast)); size_t i = 0; - signed char valid = 0; + zend_bool valid = 0; /* Check to see if this declare is preceeded only by declare statements */ while (valid == 0 && i < file_ast->children) { if (file_ast->child[i] == ast) { valid = 1; } else if (file_ast->child[i] == NULL) { - valid = -1; + /* Empty statements are not allowed prior to a declare */ + break; } else if (file_ast->child[i]->kind != ZEND_AST_DECLARE) { /* declares can only be preceeded by other declares */ - valid = -1; + break; } i++; } From d20da1d92e9f13dabe9da36645b3f72483543236 Mon Sep 17 00:00:00 2001 From: Mariano Iglesias Date: Fri, 20 Feb 2015 14:17:11 -0300 Subject: [PATCH 17/59] Renaming test to match Bug #69089 --- .../tests/{rfc-datetime_rfc3339_extended.phpt => bug69089.phpt} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename ext/date/tests/{rfc-datetime_rfc3339_extended.phpt => bug69089.phpt} (85%) diff --git a/ext/date/tests/rfc-datetime_rfc3339_extended.phpt b/ext/date/tests/bug69089.phpt similarity index 85% rename from ext/date/tests/rfc-datetime_rfc3339_extended.phpt rename to ext/date/tests/bug69089.phpt index 5235aa666b8..21a5cd125c0 100644 --- a/ext/date/tests/rfc-datetime_rfc3339_extended.phpt +++ b/ext/date/tests/bug69089.phpt @@ -1,5 +1,5 @@ --TEST-- -RFC: DateTime RFC3339 Extended +Bug #69089 (Add support for RFC3339 extended to DateTime::format) --CREDITS-- Mariano Iglesias --FILE-- From 09ac3e931cc65511114fad95aa778305c5bf6794 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sat, 21 Feb 2015 01:19:07 +0800 Subject: [PATCH 18/59] uint32_t --- Zend/zend_compile.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index dae13483eb3..9db4f284afa 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3804,12 +3804,11 @@ void zend_compile_declare(zend_ast *ast) /* {{{ */ ZVAL_COPY_VALUE(&CG(declarables).ticks, &value_zv); zval_dtor(&value_zv); } else if (zend_string_equals_literal_ci(name, "encoding")) { + uint32_t i = 0; + zend_bool valid = 0; /* Encoding declaration was already handled during parsing. Here we * only check that it is the first statement in the file. */ zend_ast_list *file_ast = zend_ast_get_list(CG(ast)); - - size_t i = 0; - zend_bool valid = 0; /* Check to see if this declare is preceeded only by declare statements */ while (valid == 0 && i < file_ast->children) { From e142e31137a85885f0cec83fe0aab1874846a077 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 20 Feb 2015 20:50:01 +0300 Subject: [PATCH 19/59] Fixed memory leak --- Zend/zend_execute_API.c | 5 ++-- ext/opcache/zend_persist.c | 61 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 0d722e5820d..fc94beeb7fc 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -595,8 +595,9 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas if (Z_REFCOUNTED_P(p)) Z_SET_REFCOUNT_P(p, refcount); } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) { zval tmp; - SEPARATE_ZVAL_NOREF(p); - + if (inline_change) { + SEPARATE_ZVAL_NOREF(p); + } zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope); if (inline_change) { zend_ast_destroy_and_free(Z_ASTVAL_P(p)); diff --git a/ext/opcache/zend_persist.c b/ext/opcache/zend_persist.c index eb442e97428..9a929be6abd 100644 --- a/ext/opcache/zend_persist.c +++ b/ext/opcache/zend_persist.c @@ -230,6 +230,63 @@ static void zend_persist_zval(zval *z) } } +static void zend_persist_zval_static(zval *z) +{ + zend_uchar flags; + void *new_ptr; + + switch (Z_TYPE_P(z)) { + case IS_STRING: + case IS_CONSTANT: + flags = Z_GC_FLAGS_P(z) & ~ (IS_STR_PERSISTENT | IS_STR_INTERNED | IS_STR_PERMANENT); + zend_accel_store_interned_string(Z_STR_P(z)); + Z_GC_FLAGS_P(z) |= flags; + Z_TYPE_FLAGS_P(z) &= ~(IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE); + break; + case IS_ARRAY: + new_ptr = zend_shared_alloc_get_xlat_entry(Z_ARR_P(z)); + if (new_ptr) { + Z_ARR_P(z) = new_ptr; + Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE; + } else { + if (Z_IMMUTABLE_P(z)) { + Z_ARR_P(z) = zend_accel_memdup(Z_ARR_P(z), sizeof(zend_array)); + zend_hash_persist_immutable(Z_ARRVAL_P(z)); + } else { + GC_REMOVE_FROM_BUFFER(Z_ARR_P(z)); + zend_accel_store(Z_ARR_P(z), sizeof(zend_array)); + zend_hash_persist(Z_ARRVAL_P(z), zend_persist_zval); + /* make immutable array */ + Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE; + GC_REFCOUNT(Z_COUNTED_P(z)) = 2; + GC_FLAGS(Z_COUNTED_P(z)) |= IS_ARRAY_IMMUTABLE; + Z_ARRVAL_P(z)->u.flags &= ~HASH_FLAG_APPLY_PROTECTION; + } + } + break; + case IS_REFERENCE: + new_ptr = zend_shared_alloc_get_xlat_entry(Z_REF_P(z)); + if (new_ptr) { + Z_REF_P(z) = new_ptr; + } else { + zend_accel_store(Z_REF_P(z), sizeof(zend_reference)); + zend_persist_zval(Z_REFVAL_P(z)); + } + break; + case IS_CONSTANT_AST: + new_ptr = zend_shared_alloc_get_xlat_entry(Z_AST_P(z)); + if (new_ptr) { + Z_AST_P(z) = new_ptr; + } else { + zend_accel_store(Z_AST_P(z), sizeof(zend_ast_ref)); + Z_ASTVAL_P(z) = zend_persist_ast(Z_ASTVAL_P(z)); + Z_TYPE_FLAGS_P(z) = IS_TYPE_CONSTANT | IS_TYPE_IMMUTABLE; + GC_REFCOUNT(Z_COUNTED_P(z)) = 2; + } + break; + } +} + static void zend_persist_zval_const(zval *z) { zend_uchar flags; @@ -280,8 +337,6 @@ static void zend_persist_zval_const(zval *z) } else { zend_accel_store(Z_AST_P(z), sizeof(zend_ast_ref)); Z_ASTVAL_P(z) = zend_persist_ast(Z_ASTVAL_P(z)); - Z_TYPE_FLAGS_P(z) = IS_TYPE_CONSTANT | IS_TYPE_IMMUTABLE; - GC_REFCOUNT(Z_COUNTED_P(z)) = 2; } break; } @@ -322,7 +377,7 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc if (stored) { op_array->static_variables = stored; } else { - zend_hash_persist(op_array->static_variables, zend_persist_zval_const); + zend_hash_persist(op_array->static_variables, zend_persist_zval_static); zend_accel_store(op_array->static_variables, sizeof(HashTable)); /* make immutable array */ GC_REFCOUNT(op_array->static_variables) = 2; From 1c31ad4f0d2e73fb32b9c06f08b42ac617da6f76 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sat, 21 Feb 2015 10:58:23 +0800 Subject: [PATCH 20/59] Unused var --- Zend/zend_ast.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Zend/zend_ast.c b/Zend/zend_ast.c index ee3ae69a34c..f888fda2890 100644 --- a/Zend/zend_ast.c +++ b/Zend/zend_ast.c @@ -890,7 +890,6 @@ static void zend_ast_export_zval(smart_str *str, zval *zv, int priority, int ind static void zend_ast_export_ex(smart_str *str, zend_ast *ast, int priority, int indent) { - zval *zv; zend_ast_decl *decl; int p, pl, pr; const char *op; From 2a724becc17afec0598d3d803da5ea30ead1eb46 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sat, 21 Feb 2015 11:02:20 +0800 Subject: [PATCH 21/59] Unused vars --- ext/opcache/zend_accelerator_util_funcs.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index 2e7f0c8da5a..ae6e8c85558 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -370,8 +370,6 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class uint idx; Bucket *p, *q; zend_ulong nIndex; - zend_class_entry *new_ce; - zend_function *new_prototype; zend_op_array *new_entry; ht->nTableSize = source->nTableSize; @@ -427,7 +425,6 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla uint idx; Bucket *p, *q; zend_ulong nIndex; - zend_class_entry *new_ce; zend_property_info *prop_info; ht->nTableSize = source->nTableSize; @@ -494,8 +491,6 @@ static void zend_class_copy_ctor(zend_class_entry **pce) { zend_class_entry *ce = *pce; zend_class_entry *old_ce = ce; - zend_class_entry *new_ce; - zend_function *new_func; *pce = ce = ARENA_REALLOC(old_ce); ce->refcount = 1; From 4629f8978e86aa20e6254e7282e6c5a4fb26796c Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sat, 21 Feb 2015 11:35:16 +0800 Subject: [PATCH 22/59] Cleanup globals initialization No needs explicit inititlize zero for globals in no-zts build. executor_globals should be initialized in zend side. --- Zend/zend.c | 29 +++++++++++++---------- ext/standard/browscap.c | 3 +-- main/main.c | 52 +++++++++++------------------------------ 3 files changed, 31 insertions(+), 53 deletions(-) diff --git a/Zend/zend.c b/Zend/zend.c index 7609869a1a6..b7a8784a69c 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -466,22 +466,28 @@ static void compiler_globals_dtor(zend_compiler_globals *compiler_globals) /* {{ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{{ */ { ZEND_TSRMLS_CACHE_UPDATE(); + zend_startup_constants(); zend_copy_constants(EG(zend_constants), GLOBAL_CONSTANTS_TABLE); zend_init_rsrc_plist(); zend_init_exception_op(); - EG(lambda_count) = 0; - ZVAL_UNDEF(&EG(user_error_handler)); - ZVAL_UNDEF(&EG(user_exception_handler)); - EG(in_autoload) = NULL; - EG(current_execute_data) = NULL; - EG(current_module) = NULL; - EG(exit_status) = 0; + executor_globals->lambda_count = 0; + ZVAL_UNDEF(&executor_globals->user_error_handler); + ZVAL_UNDEF(&executor_globals->user_exception_handler); + executor_globals->in_autoload = NULL; + executor_globals->current_execute_data = NULL; + executor_globals->current_module = NULL; + executor_globals->exit_status = 0; #if XPFPA_HAVE_CW - EG(saved_fpu_cw) = 0; + executor_globals->saved_fpu_cw = 0; #endif - EG(saved_fpu_cw_ptr) = NULL; - EG(active) = 0; + executor_globals->saved_fpu_cw_ptr = NULL; + executor_globals->active = 0; + executor_globals->bailout = NULL; + executor_globals->error_handling = EH_NORMAL; + executor_globals->exception_class = NULL; + executor_globals->exception = NULL; + executor_globals->objects_store.object_buckets = NULL; } /* }}} */ @@ -662,9 +668,8 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) / ini_scanner_globals_ctor(&ini_scanner_globals); php_scanner_globals_ctor(&language_scanner_globals); zend_set_default_compile_time_values(); - ZVAL_UNDEF(&EG(user_error_handler)); - ZVAL_UNDEF(&EG(user_exception_handler)); #endif + EG(error_reporting) = E_ALL & ~E_NOTICE; zend_interned_strings_init(); zend_startup_builtin_functions(); diff --git a/ext/standard/browscap.c b/ext/standard/browscap.c index 123a79ea123..11eeb7c907f 100644 --- a/ext/standard/browscap.c +++ b/ext/standard/browscap.c @@ -311,8 +311,7 @@ PHP_MINIT_FUNCTION(browscap) /* {{{ */ char *browscap = INI_STR("browscap"); #ifdef ZTS - ts_allocate_id(&browscap_globals_id, sizeof(browser_data), - (ts_allocate_ctor) browscap_globals_ctor, NULL); + ts_allocate_id(&browscap_globals_id, sizeof(browser_data), (ts_allocate_ctor) browscap_globals_ctor, NULL); #endif /* ctor call not really needed for non-ZTS */ diff --git a/main/main.c b/main/main.c index 944a61f86bb..35fbcb731de 100644 --- a/main/main.c +++ b/main/main.c @@ -1919,8 +1919,6 @@ static size_t php_output_wrapper(const char *str, size_t str_length) static void core_globals_ctor(php_core_globals *core_globals) { memset(core_globals, 0, sizeof(*core_globals)); - - php_startup_ticks(); } /* }}} */ #endif @@ -2034,11 +2032,6 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod int retval = SUCCESS, module_number=0; /* for REGISTER_INI_ENTRIES() */ char *php_os; zend_module_entry *module; -#ifdef ZTS - zend_executor_globals *executor_globals; - void ***tsrm_ls; - php_core_globals *core_globals; -#endif #if defined(PHP_WIN32) || (defined(NETWARE) && defined(USE_WINSOCK)) WORD wVersionRequested = MAKEWORD(2, 0); @@ -2057,11 +2050,11 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod _CrtSetReportMode(_CRT_ASSERT, 0); #endif #else - php_os=PHP_OS; + php_os = PHP_OS; #endif #ifdef ZTS - tsrm_ls = ts_resource(0); + (void)ts_resource(0); #endif #ifdef PHP_WIN32 @@ -2081,6 +2074,17 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod php_output_startup(); +#ifdef ZTS + ts_allocate_id(&core_globals_id, sizeof(php_core_globals), (ts_allocate_ctor) core_globals_ctor, (ts_allocate_dtor) core_globals_dtor); + php_startup_ticks(); +#ifdef PHP_WIN32 + ts_allocate_id(&php_win32_core_globals_id, sizeof(php_win32_core_globals), (ts_allocate_ctor) php_win32_core_globals_ctor, (ts_allocate_dtor) php_win32_core_globals_dtor); +#endif +#else + php_startup_ticks(); +#endif + gc_globals_ctor(); + zuf.error_function = php_error_cb; zuf.printf_function = php_printf; zuf.write_function = php_output_wrapper; @@ -2098,18 +2102,6 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod zuf.resolve_path_function = php_resolve_path_for_zend; zend_startup(&zuf, NULL); -#ifdef ZTS - executor_globals = ts_resource(executor_globals_id); - ts_allocate_id(&core_globals_id, sizeof(php_core_globals), (ts_allocate_ctor) core_globals_ctor, (ts_allocate_dtor) core_globals_dtor); - core_globals = ts_resource(core_globals_id); -#ifdef PHP_WIN32 - ts_allocate_id(&php_win32_core_globals_id, sizeof(php_win32_core_globals), (ts_allocate_ctor) php_win32_core_globals_ctor, (ts_allocate_dtor) php_win32_core_globals_dtor); -#endif -#else - php_startup_ticks(); -#endif - gc_globals_ctor(); - #ifdef PHP_WIN32 { OSVERSIONINFOEX *osvi = &EG(windows_version_info); @@ -2122,24 +2114,6 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod } } #endif - EG(bailout) = NULL; - EG(error_reporting) = E_ALL & ~E_NOTICE; - PG(header_is_being_sent) = 0; - SG(request_info).headers_only = 0; - SG(request_info).argv0 = NULL; - SG(request_info).argc=0; - SG(request_info).argv=(char **)NULL; - PG(connection_status) = PHP_CONNECTION_NORMAL; - PG(during_request_startup) = 0; - PG(last_error_message) = NULL; - PG(last_error_file) = NULL; - PG(last_error_lineno) = 0; - EG(error_handling) = EH_NORMAL; - EG(exception_class) = NULL; - PG(disable_functions) = NULL; - PG(disable_classes) = NULL; - EG(exception) = NULL; - EG(objects_store).object_buckets = NULL; #if HAVE_SETLOCALE setlocale(LC_CTYPE, ""); From ea94be490a5e620a86883963fa5dfa421a2477dc Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sat, 21 Feb 2015 12:36:38 +0800 Subject: [PATCH 23/59] Fixed test fails for bug68557 --- ext/spl/tests/bug68557-win32.phpt | 44 ------------------------------- ext/spl/tests/bug68557.phpt | 40 +++++++++++++--------------- 2 files changed, 19 insertions(+), 65 deletions(-) delete mode 100644 ext/spl/tests/bug68557-win32.phpt diff --git a/ext/spl/tests/bug68557-win32.phpt b/ext/spl/tests/bug68557-win32.phpt deleted file mode 100644 index 95502a53e8e..00000000000 --- a/ext/spl/tests/bug68557-win32.phpt +++ /dev/null @@ -1,44 +0,0 @@ ---TEST-- -Bug #68557 (SplFileInfo::getPathname() may be broken) ---SKIPIF-- - ---FILE-- -seek(0); -var_dump($d->current()->getPathname()); - -$d->seek(1); -var_dump($d->current()->getPathname()); - -$d->seek(0); -var_dump($d->current()->getPathname()); - -$d->seek(1); -var_dump($d->current()->getPathname()); - -$d->seek(2); -var_dump($d->current()->getPathname()); -?> ---CLEAN-- - ---EXPECTF-- -string(%d) "%s\tmp\." -string(%d) "%s\tmp\.." -string(%d) "%s\tmp\." -string(%d) "%s\tmp\.." -string(%d) "%s\tmp\a" - diff --git a/ext/spl/tests/bug68557.phpt b/ext/spl/tests/bug68557.phpt index c862bda7cf6..c1ac95257b1 100644 --- a/ext/spl/tests/bug68557.phpt +++ b/ext/spl/tests/bug68557.phpt @@ -1,11 +1,5 @@ --TEST-- Bug #68557 (SplFileInfo::getPathname() may be broken) ---SKIPIF-- - --FILE-- seek(0); -var_dump($d->current()->getPathname()); +$path0 = $d->current()->getPathname(); $d->seek(1); -var_dump($d->current()->getPathname()); - -$d->seek(0); -var_dump($d->current()->getPathname()); - -$d->seek(1); -var_dump($d->current()->getPathname()); +$path1 = $d->current()->getPathname(); $d->seek(2); -var_dump($d->current()->getPathname()); +$path2 = $d->current()->getPathname(); + +$d->seek(0); +var_dump($path0 === $d->current()->getPathname()); + +$d->seek(1); +var_dump($path1 === $d->current()->getPathname()); + +$d->seek(2); +var_dump($path2 === $d->current()->getPathname()); + +$d->seek(0); +var_dump($path0 === $d->current()->getPathname()); ?> --CLEAN-- --EXPECTF-- -string(%d) "%s/tmp/b" -string(%d) "%s/tmp/a" -string(%d) "%s/tmp/b" -string(%d) "%s/tmp/a" -string(%d) "%s/tmp/.." - +bool(true) +bool(true) +bool(true) +bool(true) From 6751f8b314e60193534f7d8c1c1d32660a27efc8 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sat, 21 Feb 2015 14:10:59 +0100 Subject: [PATCH 24/59] revisit fix for bug #65272 --- ext/standard/file.c | 4 ---- ext/standard/flock_compat.c | 20 +++++++++++++------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/ext/standard/file.c b/ext/standard/file.c index c15dd505072..c2e71d1deaa 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -356,11 +356,7 @@ PHP_FUNCTION(flock) /* flock_values contains all possible actions if (operation & 4) we won't block on the lock */ act = flock_values[act - 1] | (operation & PHP_LOCK_NB ? LOCK_NB : 0); if (php_stream_lock(stream, act)) { -#ifdef PHP_WIN32 - if (operation && errno == ERROR_INVALID_BLOCK && arg3 && PZVAL_IS_REF(arg3)) { -#else if (operation && errno == EWOULDBLOCK && arg3 && PZVAL_IS_REF(arg3)) { -#endif Z_LVAL_P(arg3) = 1; } RETURN_FALSE; diff --git a/ext/standard/flock_compat.c b/ext/standard/flock_compat.c index 973ce539056..3eb4e92d8ff 100644 --- a/ext/standard/flock_compat.c +++ b/ext/standard/flock_compat.c @@ -125,8 +125,12 @@ PHPAPI int php_flock(int fd, int operation) DWORD low = 1, high = 0; OVERLAPPED offset = {0, 0, 0, 0, NULL}; - if (hdl < 0) + DWORD err; + + if (hdl < 0) { + _set_errno(EBADF); return -1; /* error in file descriptor */ + } /* bug for bug compatible with Unix */ UnlockFileEx(hdl, 0, low, high, &offset); switch (operation & ~LOCK_NB) { /* translate to LockFileEx() op */ @@ -146,12 +150,14 @@ PHPAPI int php_flock(int fd, int operation) default: /* default */ break; } - /* Under Win32 MT library, errno is not a variable but a function call, - * which cannot be assigned to. - */ -#if !defined(PHP_WIN32) - errno = EINVAL; /* bad call */ -#endif + + err = GetLastError(); + if (ERROR_LOCK_VIOLATION == err || ERROR_SHARING_VIOLATION == err) { + _set_errno(EWOULDBLOCK); + } else { + _set_errno(EINVAL); /* bad call */ + } + return -1; } /* }}} */ From 3fd613effbd5710ffe7c5228fbb3b3e98593f789 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sat, 21 Feb 2015 14:27:14 +0100 Subject: [PATCH 25/59] removed duplicated code the exact same function is already used in ext/standard/flock_compat.* --- win32/flock.c | 84 --------------------------------------------------- win32/flock.h | 11 ------- 2 files changed, 95 deletions(-) delete mode 100644 win32/flock.c delete mode 100644 win32/flock.h diff --git a/win32/flock.c b/win32/flock.c deleted file mode 100644 index e659de65976..00000000000 --- a/win32/flock.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Program: Unix compatibility routines - * - * Author: Mark Crispin - * Networks and Distributed Computing - * Computing & Communications - * University of Washington - * Administration Building, AG-44 - * Seattle, WA 98195 - * Internet: MRC@CAC.Washington.EDU - * - * Date: 14 September 1996 - * Last Edited: 14 August 1997 - * - * Copyright 1997 by the University of Washington - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose and without fee is hereby granted, provided - * that the above copyright notice appears in all copies and that both the - * above copyright notice and this permission notice appear in supporting - * documentation, and that the name of the University of Washington not be - * used in advertising or publicity pertaining to distribution of the software - * without specific, written prior permission. This software is made available - * "as is", and - * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, - * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN - * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL, - * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT - * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION - * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - - -/* DEDICATION - - * This file is dedicated to my dog, Unix, also known as Yun-chan and - * Unix J. Terwilliker Jehosophat Aloysius Monstrosity Animal Beast. Unix - * passed away at the age of 11 1/2 on September 14, 1996, 12:18 PM PDT, after - * a two-month bout with cirrhosis of the liver. - * - * He was a dear friend, and I miss him terribly. - * - * Lift a leg, Yunie. Luv ya forever!!!! - */ - -#include "php.h" -#include -#include -#include -#include "flock.h" - -PHPAPI int flock(int fd, int op) -{ - HANDLE hdl = (HANDLE) _get_osfhandle(fd); - DWORD low = 1, high = 0; - OVERLAPPED offset = - {0, 0, 0, 0, NULL}; - if (hdl < 0) - return -1; /* error in file descriptor */ - /* bug for bug compatible with Unix */ - UnlockFileEx(hdl, 0, low, high, &offset); - switch (op & ~LOCK_NB) { /* translate to LockFileEx() op */ - case LOCK_EX: /* exclusive */ - if (LockFileEx(hdl, LOCKFILE_EXCLUSIVE_LOCK + - ((op & LOCK_NB) ? LOCKFILE_FAIL_IMMEDIATELY : 0), - 0, low, high, &offset)) - return 0; - break; - case LOCK_SH: /* shared */ - if (LockFileEx(hdl, ((op & LOCK_NB) ? LOCKFILE_FAIL_IMMEDIATELY : 0), - 0, low, high, &offset)) - return 0; - break; - case LOCK_UN: /* unlock */ - return 0; /* always succeeds */ - default: /* default */ - break; - } - errno = EINVAL; /* bad call */ - return -1; -} diff --git a/win32/flock.h b/win32/flock.h deleted file mode 100644 index d228e855dc2..00000000000 --- a/win32/flock.h +++ /dev/null @@ -1,11 +0,0 @@ -#define fsync _commit -#define ftruncate chsize - -/* For flock() emulation */ - -#define LOCK_SH 1 -#define LOCK_EX 2 -#define LOCK_NB 4 -#define LOCK_UN 8 - -PHPAPI int flock(int fd, int op); From 865a719a3f88514dfb5570e682435d5720e52ec4 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sat, 21 Feb 2015 22:17:17 +0800 Subject: [PATCH 26/59] Fixed mem issue with internal return type hinting assert --- Zend/zend_closures.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 967cb6acc62..3943b7105a2 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -63,6 +63,7 @@ ZEND_METHOD(Closure, __invoke) /* {{{ */ /* destruct the function also, then - we have allocated it in get_method */ zend_string_release(func->internal_function.function_name); efree(func); + EX(func) = NULL; } /* }}} */ From f25419f8e362faf96005ae6f78a7f901dfbcb971 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sat, 21 Feb 2015 22:44:51 +0800 Subject: [PATCH 27/59] Only do this in debug build --- Zend/zend_closures.c | 4 +++- Zend/zend_object_handlers.c | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 3943b7105a2..37f8d55bd39 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -63,7 +63,9 @@ ZEND_METHOD(Closure, __invoke) /* {{{ */ /* destruct the function also, then - we have allocated it in get_method */ zend_string_release(func->internal_function.function_name); efree(func); - EX(func) = NULL; +#if ZEND_DEBUG + execute_data->func = NULL; +#endif } /* }}} */ diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index eba9cea43cd..6c0e2f35334 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -934,7 +934,9 @@ ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ */ /* destruct the function also, then - we have allocated it in get_method */ efree_size(func, sizeof(zend_internal_function)); +#if ZEND_DEBUG execute_data->func = NULL; +#endif } /* }}} */ @@ -1155,7 +1157,9 @@ ZEND_API void zend_std_callstatic_user_call(INTERNAL_FUNCTION_PARAMETERS) /* {{{ /* destruct the function also, then - we have allocated it in get_method */ efree_size(func, sizeof(zend_internal_function)); +#if ZEND_DEBUG execute_data->func = NULL; +#endif } /* }}} */ From e3416beb030901b9dc843207e33339450f693b7d Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sun, 22 Feb 2015 00:19:06 +0800 Subject: [PATCH 28/59] Fixed segfault because resource is freed prematurely --- Zend/tests/gc_034.phpt | 11 +++++++++++ Zend/zend.c | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 Zend/tests/gc_034.phpt diff --git a/Zend/tests/gc_034.phpt b/Zend/tests/gc_034.phpt new file mode 100644 index 00000000000..29f7aae9ca4 --- /dev/null +++ b/Zend/tests/gc_034.phpt @@ -0,0 +1,11 @@ +--TEST-- +GC 033: GC in request shutdown and resource list destroy +--FILE-- + +==DONE== +--EXPECT-- +==DONE== diff --git a/Zend/zend.c b/Zend/zend.c index b7a8784a69c..b1177eda5ad 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -898,14 +898,14 @@ ZEND_API void zend_deactivate(void) /* {{{ */ shutdown_compiler(); } zend_end_try(); - zend_destroy_rsrc_list(&EG(regular_list)); - #if ZEND_DEBUG if (GC_G(gc_enabled) && !CG(unclean_shutdown)) { gc_collect_cycles(); } #endif + zend_destroy_rsrc_list(&EG(regular_list)); + #if GC_BENCH fprintf(stderr, "GC Statistics\n"); fprintf(stderr, "-------------\n"); From 078340b5636bab2de10a8013caca90292c24be2f Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sun, 22 Feb 2015 00:22:20 +0800 Subject: [PATCH 29/59] correct title --- Zend/tests/gc_034.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/tests/gc_034.phpt b/Zend/tests/gc_034.phpt index 29f7aae9ca4..2b0bd3798f7 100644 --- a/Zend/tests/gc_034.phpt +++ b/Zend/tests/gc_034.phpt @@ -1,5 +1,5 @@ --TEST-- -GC 033: GC in request shutdown and resource list destroy +GC 034: GC in request shutdown and resource list destroy --FILE-- Date: Sun, 22 Feb 2015 23:34:55 +1030 Subject: [PATCH 30/59] Fix Win32 SSPI initialization for digest authentication in cURL --- ext/curl/interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 079eaa16c7f..56cc51c4539 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -1240,7 +1240,7 @@ PHP_MINIT_FUNCTION(curl) gcry_control(GCRYCTL_SET_THREAD_CBS, &php_curl_gnutls_tsl); #endif - if (curl_global_init(CURL_GLOBAL_SSL) != CURLE_OK) { + if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) { return FAILURE; } From 8f6a013c972c40e923b2519226521144b347cce0 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 22 Feb 2015 16:46:39 +0100 Subject: [PATCH 31/59] updated NEWS --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index a0900f0d04f..84a5d2ae7c9 100644 --- a/NEWS +++ b/NEWS @@ -10,6 +10,10 @@ PHP NEWS . Fixed bug #68986 (pointer returned by php_stream_fopen_temporary_file not validated in memory.c). (nayana at ddproperty dot com) +- cURL: + . Fixed bug #69088 (PHP_MINIT_FUNCTION does not fully initialize cURL on + Win32). (Grant Pannell) + - ODBC: . Fixed bug #68964 (Allowed memory size exhausted with odbc_exec). (Anatol) From 871d51929b5ca4cd801fdc6d12ab01dac57c85cd Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sun, 22 Feb 2015 16:47:44 +0100 Subject: [PATCH 32/59] updated NEWS --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index 7c80bfaecd2..76ad94eb810 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,10 @@ . Fixed bug #68986 (pointer returned by php_stream_fopen_temporary_file not validated in memory.c). (nayana at ddproperty dot com) +- cURL: + . Fixed bug #69088 (PHP_MINIT_FUNCTION does not fully initialize cURL on + Win32). (Grant Pannell) + - ODBC: . Fixed bug #68964 (Allowed memory size exhausted with odbc_exec). (Anatol) From e12b72d3f78cc49d33bcf73ad2d4fa09b6aeff84 Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Sun, 22 Feb 2015 08:14:41 -0800 Subject: [PATCH 33/59] Fix bug #68166 We can't always efree here php_escape_html_entities can return an interned_empty_string --- main/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/main.c b/main/main.c index a98aff07554..7787ac6488f 100644 --- a/main/main.c +++ b/main/main.c @@ -1157,7 +1157,7 @@ static void php_error_cb(int type, const char *error_filename, const uint error_ size_t len; char *buf = php_escape_html_entities(buffer, buffer_len, &len, 0, ENT_COMPAT, NULL TSRMLS_CC); php_printf("%s
\n%s: %s in %s on line %d
\n%s", STR_PRINT(prepend_string), error_type_str, buf, error_filename, error_lineno, STR_PRINT(append_string)); - efree(buf); + str_efree(buf); } else { php_printf("%s
\n%s: %s in %s on line %d
\n%s", STR_PRINT(prepend_string), error_type_str, buffer, error_filename, error_lineno, STR_PRINT(append_string)); } From a9ba407ce16809a2a70724bcd481b64ba8bd550b Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Sun, 22 Feb 2015 08:14:41 -0800 Subject: [PATCH 34/59] Fix bug #68166 We can't always efree here php_escape_html_entities can return an interned_empty_string --- main/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/main.c b/main/main.c index 5e564003fec..733786e447f 100644 --- a/main/main.c +++ b/main/main.c @@ -1087,7 +1087,7 @@ static void php_error_cb(int type, const char *error_filename, const uint error_ size_t len; char *buf = php_escape_html_entities(buffer, buffer_len, &len, 0, ENT_COMPAT, NULL TSRMLS_CC); php_printf("%s
\n%s: %s in %s on line %d
\n%s", STR_PRINT(prepend_string), error_type_str, buf, error_filename, error_lineno, STR_PRINT(append_string)); - efree(buf); + str_efree(buf); } else { php_printf("%s
\n%s: %s in %s on line %d
\n%s", STR_PRINT(prepend_string), error_type_str, buffer, error_filename, error_lineno, STR_PRINT(append_string)); } From ffd2fda0f39e3432e274b4d49df485b59dcbef39 Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Sun, 22 Feb 2015 08:31:17 -0800 Subject: [PATCH 35/59] NEWS entry --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 76ad94eb810..a58a50b2a49 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,7 @@ callback). (Mike) . Fixed bug #68986 (pointer returned by php_stream_fopen_temporary_file not validated in memory.c). (nayana at ddproperty dot com) + . Fixed bug #68166 (Exception with invalid character causes segv) (Rasmus) - cURL: . Fixed bug #69088 (PHP_MINIT_FUNCTION does not fully initialize cURL on From 7ea5b3f71cb7291f88659ecf810916c34b1b6f4a Mon Sep 17 00:00:00 2001 From: Rasmus Lerdorf Date: Sun, 22 Feb 2015 08:32:32 -0800 Subject: [PATCH 36/59] NEWS entry --- NEWS | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS b/NEWS index 84a5d2ae7c9..a4f98ff3fef 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,7 @@ PHP NEWS defined in class scope). (Laruence) . Fixed bug #68986 (pointer returned by php_stream_fopen_temporary_file not validated in memory.c). (nayana at ddproperty dot com) + . Fixed bug #68166 (Exception with invalid character causes segv) (Rasmus) - cURL: . Fixed bug #69088 (PHP_MINIT_FUNCTION does not fully initialize cURL on From 591dbcabe57a32550fb73223521fa1323773628f Mon Sep 17 00:00:00 2001 From: Jakub Zelenka Date: Sun, 22 Feb 2015 20:22:47 +0000 Subject: [PATCH 37/59] Fix bug #64695 (JSON_NUMERIC_CHECK has issues with strings that are numbers plus the letter e) --- NEWS | 2 ++ ext/json/json.c | 18 +++++++----------- ext/json/tests/bug64695.phpt | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 11 deletions(-) create mode 100644 ext/json/tests/bug64695.phpt diff --git a/NEWS b/NEWS index a4f98ff3fef..fa8ce9d774e 100644 --- a/NEWS +++ b/NEWS @@ -630,6 +630,8 @@ PHP NEWS - JSON: . Fixed bug #66021 (Blank line inside empty array/object when JSON_PRETTY_PRINT is set). (Kevin Israel) + . Fixed bug #64695 (JSON_NUMERIC_CHECK has issues with strings that are + numbers plus the letter e). (Jakub Zelenka) - LDAP: . Fixed issue with null bytes in LDAP bindings. (Matthew Daley) diff --git a/ext/json/json.c b/ext/json/json.c index 5b71eb06f6e..16af7961459 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -418,18 +418,14 @@ static void json_escape_string(smart_str *buf, char *s, int len, int options TSR if ((type = is_numeric_string(s, len, &p, &d, 0)) != 0) { if (type == IS_LONG) { smart_str_append_long(buf, p); - } else if (type == IS_DOUBLE) { - if (!zend_isinf(d) && !zend_isnan(d)) { - char *tmp; - int l = spprintf(&tmp, 0, "%.*k", (int) EG(precision), d); - smart_str_appendl(buf, tmp, l); - efree(tmp); - } else { - JSON_G(error_code) = PHP_JSON_ERROR_INF_OR_NAN; - smart_str_appendc(buf, '0'); - } + return; + } else if (type == IS_DOUBLE && !zend_isinf(d) && !zend_isnan(d)) { + char *tmp; + int l = spprintf(&tmp, 0, "%.*k", (int) EG(precision), d); + smart_str_appendl(buf, tmp, l); + efree(tmp); + return; } - return; } } diff --git a/ext/json/tests/bug64695.phpt b/ext/json/tests/bug64695.phpt new file mode 100644 index 00000000000..899259f4b48 --- /dev/null +++ b/ext/json/tests/bug64695.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #64695 JSON_NUMERIC_CHECK has issues with strings that are numbers plus the letter e +--SKIPIF-- + +--FILE-- + '123343e871700'); +var_dump(json_encode($t, JSON_NUMERIC_CHECK)); + +echo "Done\n"; +?> +--EXPECT-- +string(24) "{"test":"123343e871700"}" +Done From d5a1a3342b0a9a0e571896d19e275435903bcce6 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sat, 21 Feb 2015 12:36:38 +0800 Subject: [PATCH 38/59] Fixed test fails for bug68557 --- ext/spl/tests/bug68557-win32.phpt | 44 ------------------------------- ext/spl/tests/bug68557.phpt | 40 +++++++++++++--------------- 2 files changed, 19 insertions(+), 65 deletions(-) delete mode 100644 ext/spl/tests/bug68557-win32.phpt diff --git a/ext/spl/tests/bug68557-win32.phpt b/ext/spl/tests/bug68557-win32.phpt deleted file mode 100644 index 95502a53e8e..00000000000 --- a/ext/spl/tests/bug68557-win32.phpt +++ /dev/null @@ -1,44 +0,0 @@ ---TEST-- -Bug #68557 (SplFileInfo::getPathname() may be broken) ---SKIPIF-- - ---FILE-- -seek(0); -var_dump($d->current()->getPathname()); - -$d->seek(1); -var_dump($d->current()->getPathname()); - -$d->seek(0); -var_dump($d->current()->getPathname()); - -$d->seek(1); -var_dump($d->current()->getPathname()); - -$d->seek(2); -var_dump($d->current()->getPathname()); -?> ---CLEAN-- - ---EXPECTF-- -string(%d) "%s\tmp\." -string(%d) "%s\tmp\.." -string(%d) "%s\tmp\." -string(%d) "%s\tmp\.." -string(%d) "%s\tmp\a" - diff --git a/ext/spl/tests/bug68557.phpt b/ext/spl/tests/bug68557.phpt index c862bda7cf6..c1ac95257b1 100644 --- a/ext/spl/tests/bug68557.phpt +++ b/ext/spl/tests/bug68557.phpt @@ -1,11 +1,5 @@ --TEST-- Bug #68557 (SplFileInfo::getPathname() may be broken) ---SKIPIF-- - --FILE-- seek(0); -var_dump($d->current()->getPathname()); +$path0 = $d->current()->getPathname(); $d->seek(1); -var_dump($d->current()->getPathname()); - -$d->seek(0); -var_dump($d->current()->getPathname()); - -$d->seek(1); -var_dump($d->current()->getPathname()); +$path1 = $d->current()->getPathname(); $d->seek(2); -var_dump($d->current()->getPathname()); +$path2 = $d->current()->getPathname(); + +$d->seek(0); +var_dump($path0 === $d->current()->getPathname()); + +$d->seek(1); +var_dump($path1 === $d->current()->getPathname()); + +$d->seek(2); +var_dump($path2 === $d->current()->getPathname()); + +$d->seek(0); +var_dump($path0 === $d->current()->getPathname()); ?> --CLEAN-- --EXPECTF-- -string(%d) "%s/tmp/b" -string(%d) "%s/tmp/a" -string(%d) "%s/tmp/b" -string(%d) "%s/tmp/a" -string(%d) "%s/tmp/.." - +bool(true) +bool(true) +bool(true) +bool(true) From 63ab6d8249c9f5d04fc29ed2fb3908ce6594e5f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20Unneb=C3=A4ck?= Date: Tue, 17 Jun 2014 12:28:44 +0200 Subject: [PATCH 39/59] curl: add new proxy constants --- ext/curl/interface.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 56cc51c4539..8e593f54ba0 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -845,6 +845,11 @@ PHP_MINIT_FUNCTION(curl) REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS4); REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS5); +#if LIBCURL_VERSION_NUM >= 0x071200 /* Available since 7.18.0 */ + REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS4A); + REGISTER_CURL_CONSTANT(CURLPROXY_SOCKS5_HOSTNAME); +#endif + /* Curl Share constants */ REGISTER_CURL_CONSTANT(CURLSHOPT_NONE); REGISTER_CURL_CONSTANT(CURLSHOPT_SHARE); From 1bfbb546f761266a769a3f1f85c26802cc7996a1 Mon Sep 17 00:00:00 2001 From: Julien Pauli Date: Mon, 23 Feb 2015 11:22:44 +0100 Subject: [PATCH 40/59] updated NEWS --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index fa8ce9d774e..ef42a5e32ec 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,8 @@ PHP NEWS - cURL: . Fixed bug #69088 (PHP_MINIT_FUNCTION does not fully initialize cURL on Win32). (Grant Pannell) + . Add CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5_HOSTNAME constants if supported + by libcurl. (Linus Unneback). - ODBC: . Fixed bug #68964 (Allowed memory size exhausted with odbc_exec). (Anatol) From caacaee6813da80f0803e311c47fa74c8a695daa Mon Sep 17 00:00:00 2001 From: Julien Pauli Date: Mon, 23 Feb 2015 11:23:48 +0100 Subject: [PATCH 41/59] Updated NEWS --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index a58a50b2a49..7d25d4fa739 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,8 @@ - cURL: . Fixed bug #69088 (PHP_MINIT_FUNCTION does not fully initialize cURL on Win32). (Grant Pannell) + . Add CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5_HOSTNAME constants if supported + by libcurl. (Linus Unneback). - ODBC: . Fixed bug #68964 (Allowed memory size exhausted with odbc_exec). (Anatol) From 3e6380d64bffab0c3efad81236b84d89cf743511 Mon Sep 17 00:00:00 2001 From: Popa Adrian Marius Date: Tue, 24 Feb 2015 13:58:14 +0200 Subject: [PATCH 42/59] Use Firebird default home folder, replace Interbase with Firebird --- ext/interbase/config.m4 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ext/interbase/config.m4 b/ext/interbase/config.m4 index 6aa1b368c0f..4f694caeab9 100644 --- a/ext/interbase/config.m4 +++ b/ext/interbase/config.m4 @@ -1,11 +1,11 @@ -PHP_ARG_WITH(interbase,for InterBase support, -[ --with-interbase[=DIR] Include InterBase support. DIR is the InterBase base - install directory [/usr/interbase]]) +PHP_ARG_WITH(interbase,for Firebird support, +[ --with-interbase[=DIR] Include Firebird support. DIR is the Firebird base + install directory [/opt/firebird]]) if test "$PHP_INTERBASE" != "no"; then if test "$PHP_INTERBASE" = "yes"; then - IBASE_INCDIR=/usr/interbase/include - IBASE_LIBDIR=/usr/interbase/lib + IBASE_INCDIR=/opt/firebird/include + IBASE_LIBDIR=/opt/firebird/lib else IBASE_INCDIR=$PHP_INTERBASE/include IBASE_LIBDIR=$PHP_INTERBASE/$PHP_LIBDIR @@ -23,7 +23,7 @@ if test "$PHP_INTERBASE" != "no"; then [ IBASE_LIBNAME=ib_util ], [ - AC_MSG_ERROR([libgds, libib_util or libfbclient not found! Check config.log for more information.]) + AC_MSG_ERROR([libfbclient, libgds or libib_util not found! Check config.log for more information.]) ], [ -L$IBASE_LIBDIR ]) From 745504ea2a7066588af9714f5e32523a3fff4db7 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 24 Feb 2015 17:40:25 +0300 Subject: [PATCH 43/59] Make current() and key() receive argument by value. --- ext/standard/array.c | 8 ++++---- ext/standard/basic_functions.c | 4 ++-- ext/standard/tests/array/009.phpt | 4 ++++ 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/ext/standard/array.c b/ext/standard/array.c index 701e10dff2a..c63caddda81 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -925,12 +925,12 @@ PHP_FUNCTION(current) zval *entry; #ifndef FAST_ZPP - if (zend_parse_parameters(ZEND_NUM_ARGS(), "H/", &array) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "H", &array) == FAILURE) { return; } #else ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, 0, 1) + Z_PARAM_ARRAY_OR_OBJECT_HT(array) ZEND_PARSE_PARAMETERS_END(); #endif @@ -953,12 +953,12 @@ PHP_FUNCTION(key) HashTable *array; #ifndef FAST_ZPP - if (zend_parse_parameters(ZEND_NUM_ARGS(), "H/", &array) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "H", &array) == FAILURE) { return; } #else ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_ARRAY_OR_OBJECT_HT_EX(array, 0, 1) + Z_PARAM_ARRAY_OR_OBJECT_HT(array) ZEND_PARSE_PARAMETERS_END(); #endif diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index e11b54cf232..4e1ea31294d 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -289,11 +289,11 @@ ZEND_BEGIN_ARG_INFO(arginfo_reset, 0) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_current, 0) - ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arg) + ZEND_ARG_INFO(0, arg) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_key, 0) - ZEND_ARG_INFO(ZEND_SEND_PREFER_REF, arg) + ZEND_ARG_INFO(0, arg) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_min, 0, 0, 1) diff --git a/ext/standard/tests/array/009.phpt b/ext/standard/tests/array/009.phpt index 8fa51d51ca3..e0618ad70ee 100644 --- a/ext/standard/tests/array/009.phpt +++ b/ext/standard/tests/array/009.phpt @@ -459,9 +459,13 @@ array(5) { -- Testing variation: when array is unset -- +Notice: Undefined variable: unset_array in %s on line %d + Warning: current() expects parameter 1 to be array, null given in %s on line %d NULL +Notice: Undefined variable: unset_array in %s on line %d + Warning: key() expects parameter 1 to be array, null given in %s on line %d NULL From 26be614400d972b653cdf8dce2bac6c08402b47e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 24 Feb 2015 18:34:15 +0300 Subject: [PATCH 44/59] Eliminate check on the fast path --- Zend/zend_vm_def.h | 23 ++++++++------ Zend/zend_vm_execute.h | 69 +++++++++++++++++++++++++----------------- 2 files changed, 56 insertions(+), 36 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index b21c12f23ce..ed7814d8b80 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2540,18 +2540,22 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMPVAR|CV) zend_function *fbc; zval *function_name, *func; - if (OP2_TYPE == IS_CONST && Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_STRING) { - function_name = (zval*)(EX_CONSTANT(opline->op2)+1); - if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { + if (OP2_TYPE == IS_CONST) { + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - } else if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) { - SAVE_OPLINE(); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } else { - fbc = Z_FUNC_P(func); - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc); + if (UNEXPECTED(Z_TYPE_P(EX_CONSTANT(opline->op2)) != IS_STRING)) { + goto init_fcall_complex; + } + function_name = (zval*)(EX_CONSTANT(opline->op2)+1); + if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) { + SAVE_OPLINE(); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + } else { + fbc = Z_FUNC_P(func); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc); + } } - EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, fbc, opline->extended_value, NULL, NULL, EX(call)); @@ -2563,6 +2567,7 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMPVAR|CV) zend_class_entry *called_scope; zend_object *object; +init_fcall_complex: SAVE_OPLINE(); function_name = GET_OP2_ZVAL_PTR(BP_VAR_R); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 8e3d41cb6de..31462bc07ca 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1559,18 +1559,22 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE zend_function *fbc; zval *function_name, *func; - if (IS_CONST == IS_CONST && Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_STRING) { - function_name = (zval*)(EX_CONSTANT(opline->op2)+1); - if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { + if (IS_CONST == IS_CONST) { + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - } else if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) { - SAVE_OPLINE(); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } else { - fbc = Z_FUNC_P(func); - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc); + if (UNEXPECTED(Z_TYPE_P(EX_CONSTANT(opline->op2)) != IS_STRING)) { + goto init_fcall_complex; + } + function_name = (zval*)(EX_CONSTANT(opline->op2)+1); + if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) { + SAVE_OPLINE(); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + } else { + fbc = Z_FUNC_P(func); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc); + } } - EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, fbc, opline->extended_value, NULL, NULL, EX(call)); @@ -1582,6 +1586,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE zend_class_entry *called_scope; zend_object *object; +init_fcall_complex: SAVE_OPLINE(); function_name = EX_CONSTANT(opline->op2); @@ -1950,18 +1955,22 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA zend_function *fbc; zval *function_name, *func; - if (IS_CV == IS_CONST && Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_STRING) { - function_name = (zval*)(EX_CONSTANT(opline->op2)+1); - if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { + if (IS_CV == IS_CONST) { + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - } else if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) { - SAVE_OPLINE(); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } else { - fbc = Z_FUNC_P(func); - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc); + if (UNEXPECTED(Z_TYPE_P(EX_CONSTANT(opline->op2)) != IS_STRING)) { + goto init_fcall_complex; + } + function_name = (zval*)(EX_CONSTANT(opline->op2)+1); + if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) { + SAVE_OPLINE(); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + } else { + fbc = Z_FUNC_P(func); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc); + } } - EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, fbc, opline->extended_value, NULL, NULL, EX(call)); @@ -1973,6 +1982,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HA zend_class_entry *called_scope; zend_object *object; +init_fcall_complex: SAVE_OPLINE(); function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); @@ -2139,18 +2149,22 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER(ZEND_OPCOD zend_function *fbc; zval *function_name, *func; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_STRING) { - function_name = (zval*)(EX_CONSTANT(opline->op2)+1); - if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) { + if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - } else if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) { - SAVE_OPLINE(); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2))); } else { - fbc = Z_FUNC_P(func); - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc); + if (UNEXPECTED(Z_TYPE_P(EX_CONSTANT(opline->op2)) != IS_STRING)) { + goto init_fcall_complex; + } + function_name = (zval*)(EX_CONSTANT(opline->op2)+1); + if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) { + SAVE_OPLINE(); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + } else { + fbc = Z_FUNC_P(func); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc); + } } - EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, fbc, opline->extended_value, NULL, NULL, EX(call)); @@ -2162,6 +2176,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER(ZEND_OPCOD zend_class_entry *called_scope; zend_object *object; +init_fcall_complex: SAVE_OPLINE(); function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); From e97ae4fee82e92433207d27843446ee6db0382b1 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 24 Feb 2015 18:34:37 +0300 Subject: [PATCH 45/59] Make zend_array_destroy() to free the corresponding zend_array --- Zend/zend_execute.c | 1 - Zend/zend_hash.c | 6 ++++-- Zend/zend_objects.c | 1 - Zend/zend_opcode.c | 1 - Zend/zend_variables.c | 2 -- 5 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 00a68613fcb..9e3d9f10d1a 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1694,7 +1694,6 @@ ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table) /* {{{ { if (EG(symtable_cache_ptr) >= EG(symtable_cache_limit)) { zend_array_destroy(symbol_table); - efree_size(symbol_table, sizeof(zend_array)); } else { /* clean before putting into the cache, since clean could call dtors, which could use cached hash */ diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 96e8cb2788a..afc8f9b5466 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -1113,7 +1113,7 @@ ZEND_API void zend_array_destroy(HashTable *ht) /* In some rare cases destructors of regular arrays may be changed */ if (UNEXPECTED(ht->pDestructor != ZVAL_PTR_DTOR)) { zend_hash_destroy(ht); - return; + goto free_ht; } p = ht->arData; @@ -1139,9 +1139,11 @@ ZEND_API void zend_array_destroy(HashTable *ht) zend_hash_iterators_remove(ht); SET_INCONSISTENT(HT_DESTROYED); } else if (EXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) { - return; + goto free_ht; } pefree(ht->arData, ht->u.flags & HASH_FLAG_PERSISTENT); +free_ht: + FREE_HASHTABLE(ht); } ZEND_API void zend_hash_clean(HashTable *ht) diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 60e446b4fd6..aec38110876 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -55,7 +55,6 @@ ZEND_API void zend_object_std_dtor(zend_object *object) if (object->properties) { zend_array_destroy(object->properties); - FREE_HASHTABLE(object->properties); } count = object->ce->default_properties_count; for (i = 0; i < count; i++) { diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 9e79697589c..6c3483a2506 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -322,7 +322,6 @@ ZEND_API void destroy_op_array(zend_op_array *op_array) !(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) { if (--GC_REFCOUNT(op_array->static_variables) == 0) { zend_array_destroy(op_array->static_variables); - FREE_HASHTABLE(op_array->static_variables); } } diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index de0fa1285b8..2f0c4031430 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -46,7 +46,6 @@ ZEND_API void _zval_dtor_func(zend_refcounted *p ZEND_FILE_LINE_DC) GC_TYPE(arr) = IS_NULL; GC_REMOVE_FROM_BUFFER(arr); zend_array_destroy(arr); - efree_size(arr, sizeof(zend_array)); break; } case IS_CONSTANT_AST: { @@ -102,7 +101,6 @@ ZEND_API void _zval_dtor_func_for_ptr(zend_refcounted *p ZEND_FILE_LINE_DC) GC_TYPE(arr) = IS_NULL; GC_REMOVE_FROM_BUFFER(arr); zend_array_destroy(arr); - efree_size(arr, sizeof(zend_array)); break; } case IS_CONSTANT_AST: { From 0ef5a6b409f5904a7841aed485c0de72c95b5e6f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 24 Feb 2015 19:21:21 +0300 Subject: [PATCH 46/59] Avoid unnecassary check --- Zend/zend_hash.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index afc8f9b5466..77ac3c395e8 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -1122,9 +1122,7 @@ ZEND_API void zend_array_destroy(HashTable *ht) if (ht->u.flags & HASH_FLAG_PACKED) { do { - if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) { - i_zval_ptr_dtor(&p->val ZEND_FILE_LINE_CC); - } + i_zval_ptr_dtor(&p->val ZEND_FILE_LINE_CC); } while (++p != end); } else { do { From bdf1430eeba10d444274642572b9e1ac84013080 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 24 Feb 2015 18:57:14 +0100 Subject: [PATCH 47/59] Support list($a, $b) = $a By compiling the RHS $a as a non-CV fetch. This worked as expected in PHP 5, but broke in PHP 7 due to the different assign order. However the new implementation is more general, in that it allows $a on the LHS in any place, not just the first element. --- Zend/tests/list_self_assign.phpt | 56 ++++++++++++++++++++++++++++++++ Zend/zend_compile.c | 52 ++++++++++++++++++++++++++++- 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 Zend/tests/list_self_assign.phpt diff --git a/Zend/tests/list_self_assign.phpt b/Zend/tests/list_self_assign.phpt new file mode 100644 index 00000000000..4640912696a --- /dev/null +++ b/Zend/tests/list_self_assign.phpt @@ -0,0 +1,56 @@ +--TEST-- +Test variable occuring on both LHS and RHS of list() +--FILE-- + +--EXPECT-- +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) +int(1) +int(2) +int(3) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 9db4f284afa..e7177c7cd05 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2316,6 +2316,50 @@ zend_bool zend_is_assign_to_self(zend_ast *var_ast, zend_ast *expr_ast) /* {{{ * } /* }}} */ +/* Detects if list($a, $b, $c) contains variable with given name */ +zend_bool zend_list_has_assign_to(zend_ast *list_ast, zend_string *name) /* {{{ */ +{ + zend_ast_list *list = zend_ast_get_list(list_ast); + uint32_t i; + for (i = 0; i < list->children; i++) { + zend_ast *var_ast = list->child[i]; + if (!var_ast) { + continue; + } + + /* Recursively check nested list()s */ + if (var_ast->kind == ZEND_AST_LIST && zend_list_has_assign_to(var_ast, name)) { + return 1; + } + + if (var_ast->kind == ZEND_AST_VAR && var_ast->child[0]->kind == ZEND_AST_ZVAL) { + zend_string *var_name = zval_get_string(zend_ast_get_zval(var_ast->child[0])); + zend_bool result = zend_string_equals(var_name, name); + zend_string_release(var_name); + if (result) { + return 1; + } + } + } + + return 0; +} +/* }}} */ + +/* Detects patterns like list($a, $b, $c) = $a */ +zend_bool zend_list_has_assign_to_self(zend_ast *list_ast, zend_ast *expr_ast) /* {{{ */ +{ + /* Only check simple variables on the RHS, as only CVs cause issues with this. */ + if (expr_ast->kind == ZEND_AST_VAR && expr_ast->child[0]->kind == ZEND_AST_ZVAL) { + zend_string *name = zval_get_string(zend_ast_get_zval(expr_ast->child[0])); + zend_bool result = zend_list_has_assign_to(list_ast, name); + zend_string_release(name); + return result; + } + return 0; +} +/* }}} */ + void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */ { zend_ast *var_ast = ast->child[0]; @@ -2365,7 +2409,13 @@ void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */ zend_emit_op_data(&expr_node); return; case ZEND_AST_LIST: - zend_compile_expr(&expr_node, expr_ast); + if (zend_list_has_assign_to_self(var_ast, expr_ast)) { + /* list($a, $b) = $a should evaluate the right $a first */ + zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, 0); + } else { + zend_compile_expr(&expr_node, expr_ast); + } + zend_compile_list_assign(result, var_ast, &expr_node); return; EMPTY_SWITCH_DEFAULT_CASE(); From dcb96c2e037e5198932385b573baea9a9dbf3252 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 24 Feb 2015 22:29:47 +0300 Subject: [PATCH 48/59] Split INIT_FCALL_BY_NAME inti INIT_FCALL_BY_NAME(CONST+STRING) and INIT_DYNAMIC_CALL(CONST-STRING|TMPVAR|CV) --- Zend/zend_compile.c | 5 +- Zend/zend_vm_def.h | 252 +++---- Zend/zend_vm_execute.h | 784 +++++++++----------- Zend/zend_vm_opcodes.c | 2 +- Zend/zend_vm_opcodes.h | 1 + ext/opcache/Optimizer/compact_literals.c | 4 +- ext/opcache/Optimizer/optimize_func_calls.c | 1 + ext/opcache/Optimizer/zend_optimizer.c | 7 + 8 files changed, 512 insertions(+), 544 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index e7177c7cd05..f22f1c67b7b 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2672,16 +2672,17 @@ void zend_compile_ns_call(znode *result, znode *name_node, zend_ast *args_ast) / void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_ast) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array)); - opline->opcode = ZEND_INIT_FCALL_BY_NAME; - SET_UNUSED(opline->op1); if (name_node->op_type == IS_CONST && Z_TYPE(name_node->u.constant) == IS_STRING) { + opline->opcode = ZEND_INIT_FCALL_BY_NAME; opline->op2_type = IS_CONST; opline->op2.constant = zend_add_func_name_literal(CG(active_op_array), Z_STR(name_node->u.constant)); zend_alloc_cache_slot(opline->op2.constant); } else { + opline->opcode = ZEND_INIT_DYNAMIC_CALL; SET_NODE(opline->op2, name_node); } + SET_UNUSED(opline->op1); zend_compile_call_common(result, args_ast, NULL); } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index ed7814d8b80..c6372ea557e 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2347,6 +2347,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMPVAR|UNUSED|CV, CONST|TMPVAR|CV) if (opline->opcode == ZEND_INIT_FCALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME || opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME || + opline->opcode == ZEND_INIT_DYNAMIC_CALL || opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_STATIC_METHOD_CALL || opline->opcode == ZEND_INIT_USER_CALL || @@ -2534,155 +2535,154 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMPVAR|CV) +ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST) { USE_OPLINE zend_function *fbc; zval *function_name, *func; - if (OP2_TYPE == IS_CONST) { - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - } else { - if (UNEXPECTED(Z_TYPE_P(EX_CONSTANT(opline->op2)) != IS_STRING)) { - goto init_fcall_complex; - } - function_name = (zval*)(EX_CONSTANT(opline->op2)+1); - if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) { - SAVE_OPLINE(); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } else { - fbc = Z_FUNC_P(func); - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc); - } - } - EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, NULL, NULL, EX(call)); - - /*CHECK_EXCEPTION();*/ - ZEND_VM_NEXT_OPCODE(); + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - zend_string *lcname; - zend_free_op free_op2; - zend_class_entry *called_scope; - zend_object *object; + function_name = (zval*)(EX_CONSTANT(opline->op2)+1); + if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) { + SAVE_OPLINE(); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + } else { + fbc = Z_FUNC_P(func); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc); + } + } + EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + fbc, opline->extended_value, NULL, NULL, EX(call)); -init_fcall_complex: - SAVE_OPLINE(); - function_name = GET_OP2_ZVAL_PTR(BP_VAR_R); + /*CHECK_EXCEPTION();*/ + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_HANDLER(128, ZEND_INIT_DYNAMIC_CALL, ANY, CONST|TMPVAR|CV) +{ + USE_OPLINE + zend_function *fbc; + zval *function_name, *func; + zend_string *lcname; + zend_free_op free_op2; + zend_class_entry *called_scope; + zend_object *object; + + SAVE_OPLINE(); + function_name = GET_OP2_ZVAL_PTR(BP_VAR_R); ZEND_VM_C_LABEL(try_function_name): - if (OP2_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - if (Z_STRVAL_P(function_name)[0] == '\\') { - lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0); - zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1); - } else { - lcname = zend_string_tolower(Z_STR_P(function_name)); - } - if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) { - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name)); - } - zend_string_release(lcname); + if (OP2_TYPE != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + if (Z_STRVAL_P(function_name)[0] == '\\') { + lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0); + zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1); + } else { + lcname = zend_string_tolower(Z_STR_P(function_name)); + } + if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name)); + } + zend_string_release(lcname); + FREE_OP2(); + + fbc = Z_FUNC_P(func); + called_scope = NULL; + object = NULL; + } else if (OP2_TYPE != IS_CONST && + EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && + Z_OBJ_HANDLER_P(function_name, get_closure) && + Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &called_scope, &fbc, &object) == SUCCESS) { + if (object) { + GC_REFCOUNT(object)++; + } + if (OP2_TYPE == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) { + /* Delay closure destruction until its invocation */ + fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2); + } else if (OP2_TYPE == IS_CV) { FREE_OP2(); + } + } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && + zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { + zval *obj; + zval *method; + obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0); + method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1); - fbc = Z_FUNC_P(func); - called_scope = NULL; + if (!obj || !method) { + zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1"); + } + + ZVAL_DEREF(obj); + if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) { + zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object"); + } + + ZVAL_DEREF(method); + if (Z_TYPE_P(method) != IS_STRING) { + zend_error_noreturn(E_ERROR, "Second array member is not a valid method"); + } + + if (Z_TYPE_P(obj) == IS_STRING) { object = NULL; - } else if (OP2_TYPE != IS_CONST && - EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && - Z_OBJ_HANDLER_P(function_name, get_closure) && - Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &called_scope, &fbc, &object) == SUCCESS) { - if (object) { - GC_REFCOUNT(object)++; - } - if (OP2_TYPE == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) { - /* Delay closure destruction until its invocation */ - fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2); - } else if (OP2_TYPE == IS_CV) { - FREE_OP2(); - } - } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && - zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { - zval *obj; - zval *method; - - obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0); - method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1); - - if (!obj || !method) { - zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1"); + called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0); + if (UNEXPECTED(called_scope == NULL)) { + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } - ZVAL_DEREF(obj); - if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) { - zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object"); + if (called_scope->get_static_method) { + fbc = called_scope->get_static_method(called_scope, Z_STR_P(method)); + } else { + fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL); } - - ZVAL_DEREF(method); - if (Z_TYPE_P(method) != IS_STRING) { - zend_error_noreturn(E_ERROR, "Second array member is not a valid method"); + if (UNEXPECTED(fbc == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method)); } - - if (Z_TYPE_P(obj) == IS_STRING) { - object = NULL; - called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0); - if (UNEXPECTED(called_scope == NULL)) { - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); - } - - if (called_scope->get_static_method) { - fbc = called_scope->get_static_method(called_scope, Z_STR_P(method)); - } else { - fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL); - } - if (UNEXPECTED(fbc == NULL)) { - zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method)); - } - if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { - if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { - zend_error(E_STRICT, + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { + zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically", fbc->common.scope->name->val, fbc->common.function_name->val); - } else { - zend_error_noreturn( - E_ERROR, - "Non-static method %s::%s() cannot be called statically", - fbc->common.scope->name->val, fbc->common.function_name->val); - } - } - } else { - called_scope = Z_OBJCE_P(obj); - object = Z_OBJ_P(obj); - - fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL); - if (UNEXPECTED(fbc == NULL)) { - zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method)); - } - - if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { - object = NULL; } else { - GC_REFCOUNT(object)++; /* For $this pointer */ + zend_error_noreturn( + E_ERROR, + "Non-static method %s::%s() cannot be called statically", + fbc->common.scope->name->val, fbc->common.function_name->val); } } - FREE_OP2(); - } else if ((OP2_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) { - function_name = Z_REFVAL_P(function_name); - ZEND_VM_C_GOTO(try_function_name); } else { - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - zend_error_noreturn(E_ERROR, "Function name must be a string"); - ZEND_VM_CONTINUE(); /* Never reached */ - } - EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, called_scope, object, EX(call)); + called_scope = Z_OBJCE_P(obj); + object = Z_OBJ_P(obj); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); + fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL); + if (UNEXPECTED(fbc == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method)); + } + + if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { + object = NULL; + } else { + GC_REFCOUNT(object)++; /* For $this pointer */ + } + } + FREE_OP2(); + } else if ((OP2_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) { + function_name = Z_REFVAL_P(function_name); + ZEND_VM_C_GOTO(try_function_name); + } else { + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Function name must be a string"); + ZEND_VM_CONTINUE(); /* Never reached */ } + EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + fbc, opline->extended_value, called_scope, object, EX(call)); + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV) @@ -5970,6 +5970,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) case ZEND_INIT_FCALL: case ZEND_INIT_FCALL_BY_NAME: case ZEND_INIT_NS_FCALL_BY_NAME: + case ZEND_INIT_DYNAMIC_CALL: case ZEND_INIT_USER_CALL: case ZEND_INIT_METHOD_CALL: case ZEND_INIT_STATIC_METHOD_CALL: @@ -6015,6 +6016,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) case ZEND_INIT_FCALL: case ZEND_INIT_FCALL_BY_NAME: case ZEND_INIT_NS_FCALL_BY_NAME: + case ZEND_INIT_DYNAMIC_CALL: case ZEND_INIT_USER_CALL: case ZEND_INIT_METHOD_CALL: case ZEND_INIT_STATIC_METHOD_CALL: diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 31462bc07ca..cc1df6ab905 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1260,6 +1260,7 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER case ZEND_INIT_FCALL: case ZEND_INIT_FCALL_BY_NAME: case ZEND_INIT_NS_FCALL_BY_NAME: + case ZEND_INIT_DYNAMIC_CALL: case ZEND_INIT_USER_CALL: case ZEND_INIT_METHOD_CALL: case ZEND_INIT_STATIC_METHOD_CALL: @@ -1305,6 +1306,7 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER case ZEND_INIT_FCALL: case ZEND_INIT_FCALL_BY_NAME: case ZEND_INIT_NS_FCALL_BY_NAME: + case ZEND_INIT_DYNAMIC_CALL: case ZEND_INIT_USER_CALL: case ZEND_INIT_METHOD_CALL: case ZEND_INIT_STATIC_METHOD_CALL: @@ -1559,148 +1561,147 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE zend_function *fbc; zval *function_name, *func; - if (IS_CONST == IS_CONST) { - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - } else { - if (UNEXPECTED(Z_TYPE_P(EX_CONSTANT(opline->op2)) != IS_STRING)) { - goto init_fcall_complex; - } - function_name = (zval*)(EX_CONSTANT(opline->op2)+1); - if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) { - SAVE_OPLINE(); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } else { - fbc = Z_FUNC_P(func); - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc); - } - } - EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, NULL, NULL, EX(call)); - - /*CHECK_EXCEPTION();*/ - ZEND_VM_NEXT_OPCODE(); + if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { + fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); } else { - zend_string *lcname; - zend_free_op free_op2; - zend_class_entry *called_scope; - zend_object *object; + function_name = (zval*)(EX_CONSTANT(opline->op2)+1); + if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) { + SAVE_OPLINE(); + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2))); + } else { + fbc = Z_FUNC_P(func); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc); + } + } + EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + fbc, opline->extended_value, NULL, NULL, EX(call)); -init_fcall_complex: - SAVE_OPLINE(); - function_name = EX_CONSTANT(opline->op2); + /*CHECK_EXCEPTION();*/ + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + USE_OPLINE + zend_function *fbc; + zval *function_name, *func; + zend_string *lcname; + zend_free_op free_op2; + zend_class_entry *called_scope; + zend_object *object; + + SAVE_OPLINE(); + function_name = EX_CONSTANT(opline->op2); try_function_name: - if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - if (Z_STRVAL_P(function_name)[0] == '\\') { - lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0); - zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1); - } else { - lcname = zend_string_tolower(Z_STR_P(function_name)); - } - if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) { - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name)); - } - zend_string_release(lcname); + if (IS_CONST != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + if (Z_STRVAL_P(function_name)[0] == '\\') { + lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0); + zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1); + } else { + lcname = zend_string_tolower(Z_STR_P(function_name)); + } + if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name)); + } + zend_string_release(lcname); - fbc = Z_FUNC_P(func); - called_scope = NULL; + fbc = Z_FUNC_P(func); + called_scope = NULL; + object = NULL; + } else if (IS_CONST != IS_CONST && + EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && + Z_OBJ_HANDLER_P(function_name, get_closure) && + Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &called_scope, &fbc, &object) == SUCCESS) { + if (object) { + GC_REFCOUNT(object)++; + } + if (IS_CONST == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) { + /* Delay closure destruction until its invocation */ + fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2); + } else if (IS_CONST == IS_CV) { + + } + } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && + zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { + zval *obj; + zval *method; + obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0); + method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1); + + if (!obj || !method) { + zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1"); + } + + ZVAL_DEREF(obj); + if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) { + zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object"); + } + + ZVAL_DEREF(method); + if (Z_TYPE_P(method) != IS_STRING) { + zend_error_noreturn(E_ERROR, "Second array member is not a valid method"); + } + + if (Z_TYPE_P(obj) == IS_STRING) { object = NULL; - } else if (IS_CONST != IS_CONST && - EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && - Z_OBJ_HANDLER_P(function_name, get_closure) && - Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &called_scope, &fbc, &object) == SUCCESS) { - if (object) { - GC_REFCOUNT(object)++; - } - if (IS_CONST == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) { - /* Delay closure destruction until its invocation */ - fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2); - } else if (IS_CONST == IS_CV) { - - } - } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && - zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { - zval *obj; - zval *method; - - obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0); - method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1); - - if (!obj || !method) { - zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1"); + called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0); + if (UNEXPECTED(called_scope == NULL)) { + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } - ZVAL_DEREF(obj); - if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) { - zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object"); + if (called_scope->get_static_method) { + fbc = called_scope->get_static_method(called_scope, Z_STR_P(method)); + } else { + fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL); } - - ZVAL_DEREF(method); - if (Z_TYPE_P(method) != IS_STRING) { - zend_error_noreturn(E_ERROR, "Second array member is not a valid method"); + if (UNEXPECTED(fbc == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method)); } - - if (Z_TYPE_P(obj) == IS_STRING) { - object = NULL; - called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0); - if (UNEXPECTED(called_scope == NULL)) { - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); - } - - if (called_scope->get_static_method) { - fbc = called_scope->get_static_method(called_scope, Z_STR_P(method)); - } else { - fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL); - } - if (UNEXPECTED(fbc == NULL)) { - zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method)); - } - if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { - if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { - zend_error(E_STRICT, + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { + zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically", fbc->common.scope->name->val, fbc->common.function_name->val); - } else { - zend_error_noreturn( - E_ERROR, - "Non-static method %s::%s() cannot be called statically", - fbc->common.scope->name->val, fbc->common.function_name->val); - } - } - } else { - called_scope = Z_OBJCE_P(obj); - object = Z_OBJ_P(obj); - - fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL); - if (UNEXPECTED(fbc == NULL)) { - zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method)); - } - - if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { - object = NULL; } else { - GC_REFCOUNT(object)++; /* For $this pointer */ + zend_error_noreturn( + E_ERROR, + "Non-static method %s::%s() cannot be called statically", + fbc->common.scope->name->val, fbc->common.function_name->val); } } - - } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) { - function_name = Z_REFVAL_P(function_name); - goto try_function_name; } else { - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - zend_error_noreturn(E_ERROR, "Function name must be a string"); - ZEND_VM_CONTINUE(); /* Never reached */ - } - EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, called_scope, object, EX(call)); + called_scope = Z_OBJCE_P(obj); + object = Z_OBJ_P(obj); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); + fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL); + if (UNEXPECTED(fbc == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method)); + } + + if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { + object = NULL; + } else { + GC_REFCOUNT(object)++; /* For $this pointer */ + } + } + + } else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) { + function_name = Z_REFVAL_P(function_name); + goto try_function_name; + } else { + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Function name must be a string"); + ZEND_VM_CONTINUE(); /* Never reached */ } + EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + fbc, opline->extended_value, called_scope, object, EX(call)); + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static int ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_NAME_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -1949,154 +1950,128 @@ try_class_name: } } -static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static int ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_function *fbc; zval *function_name, *func; + zend_string *lcname; + zend_free_op free_op2; + zend_class_entry *called_scope; + zend_object *object; - if (IS_CV == IS_CONST) { - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - } else { - if (UNEXPECTED(Z_TYPE_P(EX_CONSTANT(opline->op2)) != IS_STRING)) { - goto init_fcall_complex; - } - function_name = (zval*)(EX_CONSTANT(opline->op2)+1); - if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) { - SAVE_OPLINE(); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } else { - fbc = Z_FUNC_P(func); - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc); - } - } - EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, NULL, NULL, EX(call)); - - /*CHECK_EXCEPTION();*/ - ZEND_VM_NEXT_OPCODE(); - } else { - zend_string *lcname; - zend_free_op free_op2; - zend_class_entry *called_scope; - zend_object *object; - -init_fcall_complex: - SAVE_OPLINE(); - function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + SAVE_OPLINE(); + function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); try_function_name: - if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - if (Z_STRVAL_P(function_name)[0] == '\\') { - lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0); - zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1); - } else { - lcname = zend_string_tolower(Z_STR_P(function_name)); - } - if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) { - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name)); - } - zend_string_release(lcname); + if (IS_CV != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + if (Z_STRVAL_P(function_name)[0] == '\\') { + lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0); + zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1); + } else { + lcname = zend_string_tolower(Z_STR_P(function_name)); + } + if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name)); + } + zend_string_release(lcname); - fbc = Z_FUNC_P(func); - called_scope = NULL; + fbc = Z_FUNC_P(func); + called_scope = NULL; + object = NULL; + } else if (IS_CV != IS_CONST && + EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && + Z_OBJ_HANDLER_P(function_name, get_closure) && + Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &called_scope, &fbc, &object) == SUCCESS) { + if (object) { + GC_REFCOUNT(object)++; + } + if (IS_CV == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) { + /* Delay closure destruction until its invocation */ + fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2); + } else if (IS_CV == IS_CV) { + + } + } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && + zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { + zval *obj; + zval *method; + obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0); + method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1); + + if (!obj || !method) { + zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1"); + } + + ZVAL_DEREF(obj); + if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) { + zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object"); + } + + ZVAL_DEREF(method); + if (Z_TYPE_P(method) != IS_STRING) { + zend_error_noreturn(E_ERROR, "Second array member is not a valid method"); + } + + if (Z_TYPE_P(obj) == IS_STRING) { object = NULL; - } else if (IS_CV != IS_CONST && - EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && - Z_OBJ_HANDLER_P(function_name, get_closure) && - Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &called_scope, &fbc, &object) == SUCCESS) { - if (object) { - GC_REFCOUNT(object)++; - } - if (IS_CV == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) { - /* Delay closure destruction until its invocation */ - fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2); - } else if (IS_CV == IS_CV) { - - } - } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && - zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { - zval *obj; - zval *method; - - obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0); - method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1); - - if (!obj || !method) { - zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1"); + called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0); + if (UNEXPECTED(called_scope == NULL)) { + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } - ZVAL_DEREF(obj); - if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) { - zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object"); + if (called_scope->get_static_method) { + fbc = called_scope->get_static_method(called_scope, Z_STR_P(method)); + } else { + fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL); } - - ZVAL_DEREF(method); - if (Z_TYPE_P(method) != IS_STRING) { - zend_error_noreturn(E_ERROR, "Second array member is not a valid method"); + if (UNEXPECTED(fbc == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method)); } - - if (Z_TYPE_P(obj) == IS_STRING) { - object = NULL; - called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0); - if (UNEXPECTED(called_scope == NULL)) { - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); - } - - if (called_scope->get_static_method) { - fbc = called_scope->get_static_method(called_scope, Z_STR_P(method)); - } else { - fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL); - } - if (UNEXPECTED(fbc == NULL)) { - zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method)); - } - if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { - if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { - zend_error(E_STRICT, + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { + zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically", fbc->common.scope->name->val, fbc->common.function_name->val); - } else { - zend_error_noreturn( - E_ERROR, - "Non-static method %s::%s() cannot be called statically", - fbc->common.scope->name->val, fbc->common.function_name->val); - } - } - } else { - called_scope = Z_OBJCE_P(obj); - object = Z_OBJ_P(obj); - - fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL); - if (UNEXPECTED(fbc == NULL)) { - zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method)); - } - - if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { - object = NULL; } else { - GC_REFCOUNT(object)++; /* For $this pointer */ + zend_error_noreturn( + E_ERROR, + "Non-static method %s::%s() cannot be called statically", + fbc->common.scope->name->val, fbc->common.function_name->val); } } - - } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) { - function_name = Z_REFVAL_P(function_name); - goto try_function_name; } else { - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - zend_error_noreturn(E_ERROR, "Function name must be a string"); - ZEND_VM_CONTINUE(); /* Never reached */ - } - EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, called_scope, object, EX(call)); + called_scope = Z_OBJCE_P(obj); + object = Z_OBJ_P(obj); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); + fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL); + if (UNEXPECTED(fbc == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method)); + } + + if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { + object = NULL; + } else { + GC_REFCOUNT(object)++; /* For $this pointer */ + } + } + + } else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) { + function_name = Z_REFVAL_P(function_name); + goto try_function_name; + } else { + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Function name must be a string"); + ZEND_VM_CONTINUE(); /* Never reached */ } + EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + fbc, opline->extended_value, called_scope, object, EX(call)); + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -2143,155 +2118,129 @@ try_class_name: } } -static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +static int ZEND_FASTCALL ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE zend_function *fbc; zval *function_name, *func; + zend_string *lcname; + zend_free_op free_op2; + zend_class_entry *called_scope; + zend_object *object; - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - if (EXPECTED(CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))))) { - fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2))); - } else { - if (UNEXPECTED(Z_TYPE_P(EX_CONSTANT(opline->op2)) != IS_STRING)) { - goto init_fcall_complex; - } - function_name = (zval*)(EX_CONSTANT(opline->op2)+1); - if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) { - SAVE_OPLINE(); - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2))); - } else { - fbc = Z_FUNC_P(func); - CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc); - } - } - EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, NULL, NULL, EX(call)); - - /*CHECK_EXCEPTION();*/ - ZEND_VM_NEXT_OPCODE(); - } else { - zend_string *lcname; - zend_free_op free_op2; - zend_class_entry *called_scope; - zend_object *object; - -init_fcall_complex: - SAVE_OPLINE(); - function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + SAVE_OPLINE(); + function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); try_function_name: - if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { - if (Z_STRVAL_P(function_name)[0] == '\\') { - lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0); - zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1); - } else { - lcname = zend_string_tolower(Z_STR_P(function_name)); - } - if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) { - zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name)); - } - zend_string_release(lcname); + if ((IS_TMP_VAR|IS_VAR) != IS_CONST && EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { + if (Z_STRVAL_P(function_name)[0] == '\\') { + lcname = zend_string_alloc(Z_STRLEN_P(function_name) - 1, 0); + zend_str_tolower_copy(lcname->val, Z_STRVAL_P(function_name) + 1, Z_STRLEN_P(function_name) - 1); + } else { + lcname = zend_string_tolower(Z_STR_P(function_name)); + } + if (UNEXPECTED((func = zend_hash_find(EG(function_table), lcname)) == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name)); + } + zend_string_release(lcname); + zval_ptr_dtor_nogc(free_op2); + + fbc = Z_FUNC_P(func); + called_scope = NULL; + object = NULL; + } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && + EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && + Z_OBJ_HANDLER_P(function_name, get_closure) && + Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &called_scope, &fbc, &object) == SUCCESS) { + if (object) { + GC_REFCOUNT(object)++; + } + if ((IS_TMP_VAR|IS_VAR) == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) { + /* Delay closure destruction until its invocation */ + fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2); + } else if ((IS_TMP_VAR|IS_VAR) == IS_CV) { zval_ptr_dtor_nogc(free_op2); + } + } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && + zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { + zval *obj; + zval *method; + obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0); + method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1); - fbc = Z_FUNC_P(func); - called_scope = NULL; + if (!obj || !method) { + zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1"); + } + + ZVAL_DEREF(obj); + if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) { + zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object"); + } + + ZVAL_DEREF(method); + if (Z_TYPE_P(method) != IS_STRING) { + zend_error_noreturn(E_ERROR, "Second array member is not a valid method"); + } + + if (Z_TYPE_P(obj) == IS_STRING) { object = NULL; - } else if ((IS_TMP_VAR|IS_VAR) != IS_CONST && - EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) && - Z_OBJ_HANDLER_P(function_name, get_closure) && - Z_OBJ_HANDLER_P(function_name, get_closure)(function_name, &called_scope, &fbc, &object) == SUCCESS) { - if (object) { - GC_REFCOUNT(object)++; - } - if ((IS_TMP_VAR|IS_VAR) == IS_VAR && (fbc->common.fn_flags & ZEND_ACC_CLOSURE)) { - /* Delay closure destruction until its invocation */ - fbc->common.prototype = (zend_function*)Z_OBJ_P(free_op2); - } else if ((IS_TMP_VAR|IS_VAR) == IS_CV) { - zval_ptr_dtor_nogc(free_op2); - } - } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && - zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { - zval *obj; - zval *method; - - obj = zend_hash_index_find(Z_ARRVAL_P(function_name), 0); - method = zend_hash_index_find(Z_ARRVAL_P(function_name), 1); - - if (!obj || !method) { - zend_error_noreturn(E_ERROR, "Array callback has to contain indices 0 and 1"); + called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0); + if (UNEXPECTED(called_scope == NULL)) { + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } - ZVAL_DEREF(obj); - if (Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) { - zend_error_noreturn(E_ERROR, "First array member is not a valid class name or object"); + if (called_scope->get_static_method) { + fbc = called_scope->get_static_method(called_scope, Z_STR_P(method)); + } else { + fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL); } - - ZVAL_DEREF(method); - if (Z_TYPE_P(method) != IS_STRING) { - zend_error_noreturn(E_ERROR, "Second array member is not a valid method"); + if (UNEXPECTED(fbc == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method)); } - - if (Z_TYPE_P(obj) == IS_STRING) { - object = NULL; - called_scope = zend_fetch_class_by_name(Z_STR_P(obj), NULL, 0); - if (UNEXPECTED(called_scope == NULL)) { - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); - } - - if (called_scope->get_static_method) { - fbc = called_scope->get_static_method(called_scope, Z_STR_P(method)); - } else { - fbc = zend_std_get_static_method(called_scope, Z_STR_P(method), NULL); - } - if (UNEXPECTED(fbc == NULL)) { - zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", called_scope->name->val, Z_STRVAL_P(method)); - } - if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { - if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { - zend_error(E_STRICT, + if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { + if (fbc->common.fn_flags & ZEND_ACC_ALLOW_STATIC) { + zend_error(E_STRICT, "Non-static method %s::%s() should not be called statically", fbc->common.scope->name->val, fbc->common.function_name->val); - } else { - zend_error_noreturn( - E_ERROR, - "Non-static method %s::%s() cannot be called statically", - fbc->common.scope->name->val, fbc->common.function_name->val); - } - } - } else { - called_scope = Z_OBJCE_P(obj); - object = Z_OBJ_P(obj); - - fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL); - if (UNEXPECTED(fbc == NULL)) { - zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method)); - } - - if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { - object = NULL; } else { - GC_REFCOUNT(object)++; /* For $this pointer */ + zend_error_noreturn( + E_ERROR, + "Non-static method %s::%s() cannot be called statically", + fbc->common.scope->name->val, fbc->common.function_name->val); } } - zval_ptr_dtor_nogc(free_op2); - } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) { - function_name = Z_REFVAL_P(function_name); - goto try_function_name; } else { - if (UNEXPECTED(EG(exception) != NULL)) { - HANDLE_EXCEPTION(); - } - zend_error_noreturn(E_ERROR, "Function name must be a string"); - ZEND_VM_CONTINUE(); /* Never reached */ - } - EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, - fbc, opline->extended_value, called_scope, object, EX(call)); + called_scope = Z_OBJCE_P(obj); + object = Z_OBJ_P(obj); - CHECK_EXCEPTION(); - ZEND_VM_NEXT_OPCODE(); + fbc = Z_OBJ_HT_P(obj)->get_method(&object, Z_STR_P(method), NULL); + if (UNEXPECTED(fbc == NULL)) { + zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", object->ce->name->val, Z_STRVAL_P(method)); + } + + if ((fbc->common.fn_flags & ZEND_ACC_STATIC) != 0) { + object = NULL; + } else { + GC_REFCOUNT(object)++; /* For $this pointer */ + } + } + zval_ptr_dtor_nogc(free_op2); + } else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) { + function_name = Z_REFVAL_P(function_name); + goto try_function_name; + } else { + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + zend_error_noreturn(E_ERROR, "Function name must be a string"); + ZEND_VM_CONTINUE(); /* Never reached */ } + EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION, + fbc, opline->extended_value, called_scope, object, EX(call)); + + CHECK_EXCEPTION(); + ZEND_VM_NEXT_OPCODE(); } static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) @@ -19481,6 +19430,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O if (opline->opcode == ZEND_INIT_FCALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME || opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME || + opline->opcode == ZEND_INIT_DYNAMIC_CALL || opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_STATIC_METHOD_CALL || opline->opcode == ZEND_INIT_USER_CALL || @@ -21687,6 +21637,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO if (opline->opcode == ZEND_INIT_FCALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME || opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME || + opline->opcode == ZEND_INIT_DYNAMIC_CALL || opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_STATIC_METHOD_CALL || opline->opcode == ZEND_INIT_USER_CALL || @@ -23077,6 +23028,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_ if (opline->opcode == ZEND_INIT_FCALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME || opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME || + opline->opcode == ZEND_INIT_DYNAMIC_CALL || opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_STATIC_METHOD_CALL || opline->opcode == ZEND_INIT_USER_CALL || @@ -26568,6 +26520,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD if (opline->opcode == ZEND_INIT_FCALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME || opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME || + opline->opcode == ZEND_INIT_DYNAMIC_CALL || opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_STATIC_METHOD_CALL || opline->opcode == ZEND_INIT_USER_CALL || @@ -30796,6 +30749,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H if (opline->opcode == ZEND_INIT_FCALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME || opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME || + opline->opcode == ZEND_INIT_DYNAMIC_CALL || opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_STATIC_METHOD_CALL || opline->opcode == ZEND_INIT_USER_CALL || @@ -32765,6 +32719,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCO if (opline->opcode == ZEND_INIT_FCALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME || opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME || + opline->opcode == ZEND_INIT_DYNAMIC_CALL || opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_STATIC_METHOD_CALL || opline->opcode == ZEND_INIT_USER_CALL || @@ -34437,6 +34392,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER(ZEND_O if (opline->opcode == ZEND_INIT_FCALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME || opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME || + opline->opcode == ZEND_INIT_DYNAMIC_CALL || opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_STATIC_METHOD_CALL || opline->opcode == ZEND_INIT_USER_CALL || @@ -36051,6 +36007,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCO if (opline->opcode == ZEND_INIT_FCALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME || opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME || + opline->opcode == ZEND_INIT_DYNAMIC_CALL || opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_STATIC_METHOD_CALL || opline->opcode == ZEND_INIT_USER_CALL || @@ -36710,6 +36667,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_ if (opline->opcode == ZEND_INIT_FCALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME || opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME || + opline->opcode == ZEND_INIT_DYNAMIC_CALL || opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_STATIC_METHOD_CALL || opline->opcode == ZEND_INIT_USER_CALL || @@ -38448,30 +38406,30 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_INIT_FCALL_BY_NAME_SPEC_CONST_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_TMPVAR_HANDLER, ZEND_NULL_HANDLER, - ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, ZEND_DO_FCALL_SPEC_HANDLER, ZEND_DO_FCALL_SPEC_HANDLER, ZEND_DO_FCALL_SPEC_HANDLER, @@ -40172,31 +40130,31 @@ void zend_init_opcodes_handlers(void) ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, ZEND_NULL_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, ZEND_NULL_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, ZEND_NULL_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, ZEND_NULL_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_CONST_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_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_NULL_HANDLER, - ZEND_NULL_HANDLER, - ZEND_NULL_HANDLER, + ZEND_INIT_DYNAMIC_CALL_SPEC_CV_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 33f67e6f4b7..1ab2a9e0fa0 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -150,7 +150,7 @@ const char *zend_vm_opcodes_map[171] = { "ZEND_FE_RESET_RW", "ZEND_FE_FETCH_RW", "ZEND_FE_FREE", - NULL, + "ZEND_INIT_DYNAMIC_CALL", NULL, NULL, NULL, diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index 4764e390941..d21ff08e7f9 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -152,6 +152,7 @@ END_EXTERN_C() #define ZEND_FE_RESET_RW 125 #define ZEND_FE_FETCH_RW 126 #define ZEND_FE_FREE 127 +#define ZEND_INIT_DYNAMIC_CALL 128 #define ZEND_PRE_INC_OBJ 132 #define ZEND_PRE_DEC_OBJ 133 #define ZEND_POST_INC_OBJ 134 diff --git a/ext/opcache/Optimizer/compact_literals.c b/ext/opcache/Optimizer/compact_literals.c index 3e44769cc99..1ac7265e1c8 100644 --- a/ext/opcache/Optimizer/compact_literals.c +++ b/ext/opcache/Optimizer/compact_literals.c @@ -139,9 +139,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 1); break; case ZEND_INIT_FCALL_BY_NAME: - if (ZEND_OP2_TYPE(opline) == IS_CONST) { - LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 2); - } + LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 2); break; case ZEND_INIT_NS_FCALL_BY_NAME: LITERAL_INFO(opline->op2.constant, LITERAL_FUNC, 1, 1, 3); diff --git a/ext/opcache/Optimizer/optimize_func_calls.c b/ext/opcache/Optimizer/optimize_func_calls.c index 78c6def6251..a83adab5ec1 100644 --- a/ext/opcache/Optimizer/optimize_func_calls.c +++ b/ext/opcache/Optimizer/optimize_func_calls.c @@ -66,6 +66,7 @@ void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) } /* break missing intentionally */ case ZEND_NEW: + case ZEND_INIT_DYNAMIC_CALL: case ZEND_INIT_METHOD_CALL: case ZEND_INIT_STATIC_METHOD_CALL: case ZEND_INIT_FCALL: diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 191e13ca1dd..eab51c7f66f 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -180,6 +180,13 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array, zend_optimizer_add_literal(op_array, val); zend_string_hash_val(Z_STR(op_array->literals[opline->op2.constant+1])); break; + case ZEND_INIT_DYNAMIC_CALL: + opline->opcode = ZEND_INIT_FCALL_BY_NAME; + Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot++; + zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); + zend_optimizer_add_literal(op_array, val); + zend_string_hash_val(Z_STR(op_array->literals[opline->op2.constant+1])); + break; case ZEND_INIT_METHOD_CALL: case ZEND_INIT_STATIC_METHOD_CALL: zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); From 5f278e4d3a97ea0777e471424b52110386f1742e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 25 Feb 2015 01:52:35 +0300 Subject: [PATCH 49/59] Use cache_slot offsets instead of indexes (simplify run-time instructions) --- Zend/zend_compile.c | 7 +- Zend/zend_compile.h | 2 +- Zend/zend_execute.c | 11 +- Zend/zend_execute.h | 16 +- Zend/zend_opcode.c | 2 +- Zend/zend_vm_def.h | 44 +-- Zend/zend_vm_execute.h | 450 +++++++++++------------ ext/opcache/Optimizer/compact_literals.c | 10 +- ext/opcache/Optimizer/zend_optimizer.c | 20 +- 9 files changed, 287 insertions(+), 275 deletions(-) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index f22f1c67b7b..9fbfa1f82f8 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -52,15 +52,16 @@ static inline void zend_alloc_cache_slot(uint32_t literal) { zend_op_array *op_array = CG(active_op_array); - Z_CACHE_SLOT(op_array->literals[literal]) = op_array->last_cache_slot++; + Z_CACHE_SLOT(op_array->literals[literal]) = op_array->cache_size; + op_array->cache_size += sizeof(void*); } #define POLYMORPHIC_CACHE_SLOT_SIZE 2 static inline void zend_alloc_polymorphic_cache_slot(uint32_t literal) { zend_op_array *op_array = CG(active_op_array); - Z_CACHE_SLOT(op_array->literals[literal]) = op_array->last_cache_slot; - op_array->last_cache_slot += POLYMORPHIC_CACHE_SLOT_SIZE; + Z_CACHE_SLOT(op_array->literals[literal]) = op_array->cache_size; + op_array->cache_size += POLYMORPHIC_CACHE_SLOT_SIZE * sizeof(void*); } ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 0a4c146d28c..6073e240f32 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -352,7 +352,7 @@ struct _zend_op_array { int last_literal; zval *literals; - int last_cache_slot; + int cache_size; void **run_time_cache; void *reserved[ZEND_MAX_RESERVED_RESOURCES]; diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 9e3d9f10d1a..b016df1e252 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1804,7 +1804,8 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu } if (UNEXPECTED(!op_array->run_time_cache)) { - op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*)); + op_array->run_time_cache = zend_arena_alloc(&CG(arena), op_array->cache_size); + memset(op_array->run_time_cache, 0, op_array->cache_size); } EX_LOAD_RUN_TIME_CACHE(op_array); EX_LOAD_LITERALS(op_array); @@ -1829,7 +1830,8 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu } if (!op_array->run_time_cache) { - op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*)); + op_array->run_time_cache = emalloc(op_array->cache_size); + memset(op_array->run_time_cache, 0, op_array->cache_size); } EX_LOAD_RUN_TIME_CACHE(op_array); EX_LOAD_LITERALS(op_array); @@ -1906,10 +1908,11 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da if (!op_array->run_time_cache) { if (op_array->function_name) { - op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*)); + op_array->run_time_cache = zend_arena_alloc(&CG(arena), op_array->cache_size); } else { - op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*)); + op_array->run_time_cache = emalloc(op_array->cache_size); } + memset(op_array->run_time_cache, 0, op_array->cache_size); } EX_LOAD_RUN_TIME_CACHE(op_array); EX_LOAD_LITERALS(op_array); diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 0fdf76453d0..4298f6bdd68 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -256,21 +256,25 @@ ZEND_API int zend_do_fcall(ZEND_OPCODE_HANDLER_ARGS); ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table); void zend_free_compiled_variables(zend_execute_data *execute_data); +#define CACHE_ADDR(num) \ + ((void**)((char*)EX_RUN_TIME_CACHE() + (num))) + #define CACHED_PTR(num) \ - EX_RUN_TIME_CACHE()[(num)] + ((void**)((char*)EX_RUN_TIME_CACHE() + (num)))[0] #define CACHE_PTR(num, ptr) do { \ - EX_RUN_TIME_CACHE()[(num)] = (ptr); \ + ((void**)((char*)EX_RUN_TIME_CACHE() + (num)))[0] = (ptr); \ } while (0) #define CACHED_POLYMORPHIC_PTR(num, ce) \ - ((EX_RUN_TIME_CACHE()[(num)] == (ce)) ? \ - EX_RUN_TIME_CACHE()[(num) + 1] : \ + ((((void**)((char*)EX_RUN_TIME_CACHE() + (num)))[0] == (void*)(ce)) ? \ + ((void**)((char*)EX_RUN_TIME_CACHE() + (num)))[1] : \ NULL) #define CACHE_POLYMORPHIC_PTR(num, ce, ptr) do { \ - EX_RUN_TIME_CACHE()[(num)] = (ce); \ - EX_RUN_TIME_CACHE()[(num) + 1] = (ptr); \ + void **slot = (void**)((char*)EX_RUN_TIME_CACHE() + (num)); \ + slot[0] = (ce); \ + slot[1] = (ptr); \ } while (0) #define CACHED_PTR_EX(slot) \ diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 6c3483a2506..643f51b9266 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -91,7 +91,7 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz op_array->literals = NULL; op_array->run_time_cache = NULL; - op_array->last_cache_slot = 0; + op_array->cache_size = 0; memset(op_array->reserved, 0, ZEND_MAX_RESERVED_RESOURCES * sizeof(void*)); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index c6372ea557e..8e2051e6c0a 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -377,7 +377,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR| /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -391,7 +391,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR| zval rv; if (Z_OBJ_HT_P(object)->read_property && - (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { + (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) { zval rv; zval *value = Z_OBJ_HT_P(z)->get(z, &rv); @@ -404,7 +404,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR| ZVAL_DEREF(z); SEPARATE_ZVAL_NOREF(z); binary_op(z, z, value); - Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), z); } @@ -777,7 +777,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -790,7 +790,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C zval rv; if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval rv; @@ -807,7 +807,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(retval, z); } - Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); @@ -864,7 +864,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR| /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); ZVAL_COPY_VALUE(retval, zptr); @@ -874,7 +874,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR| } else { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { zval rv; - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -890,7 +890,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR| ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); - Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(&z_copy); zval_ptr_dtor(z); } else { @@ -1131,7 +1131,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED|CONST|V if (OP1_TYPE == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -1438,7 +1438,7 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|CV) if (OP2_TYPE == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -1460,7 +1460,7 @@ ZEND_VM_C_LABEL(fetch_obj_r_no_object): zend_error(E_NOTICE, "Trying to get property of non-object"); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -1489,7 +1489,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMPVAR|CV) zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); FREE_OP2(); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -1513,7 +1513,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMPVAR|CV) if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); FREE_OP2(); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -1553,7 +1553,7 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV) if (OP2_TYPE == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -1575,7 +1575,7 @@ ZEND_VM_C_LABEL(fetch_obj_is_no_object): ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -1609,7 +1609,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMPV if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); FREE_OP2(); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -1635,7 +1635,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMPVAR|CV) if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); FREE_OP2(); if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -1696,7 +1696,7 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV) if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, OP1_TYPE, property_name, OP2_TYPE, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property_name)) : NULL)); + zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, OP1_TYPE, property_name, OP2_TYPE, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); FREE_OP2(); FREE_OP1_VAR_PTR(); /* assign_obj has two opcodes! */ @@ -4659,7 +4659,7 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV) } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } @@ -5321,7 +5321,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR) if (OP1_TYPE == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -5528,7 +5528,7 @@ ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|CV, CONST| ZEND_VM_C_LABEL(isset_no_object): result = ((opline->extended_value & ZEND_ISSET) == 0); } else { - result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); if ((opline->extended_value & ZEND_ISSET) == 0) { result = !result; } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index cc1df6ab905..04a8787262d 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3843,7 +3843,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type if (IS_CONST == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -4083,7 +4083,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_ if (IS_CONST == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -4105,7 +4105,7 @@ fetch_obj_r_no_object: zend_error(E_NOTICE, "Trying to get property of non-object"); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -4148,7 +4148,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE if (IS_CONST == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -4170,7 +4170,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -4203,7 +4203,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_ if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -4774,7 +4774,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_CONST_HANDLER(ZEND_O if (IS_CONST == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -4979,7 +4979,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CONST_HANDLER(Z isset_no_object: result = ((opline->extended_value & ZEND_ISSET) == 0); } else { - result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); if ((opline->extended_value & ZEND_ISSET) == 0) { result = !result; } @@ -5391,7 +5391,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type, if (IS_CONST == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -5648,7 +5648,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPC if (IS_CONST == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -5868,7 +5868,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ if (IS_CONST == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -6422,7 +6422,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_ if (IS_CONST == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -7025,7 +7025,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAN if (IS_CV == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -7047,7 +7047,7 @@ fetch_obj_r_no_object: zend_error(E_NOTICE, "Trying to get property of non-object"); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -7090,7 +7090,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HA if (IS_CV == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -7112,7 +7112,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -7145,7 +7145,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPC if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, IS_CV, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -7664,7 +7664,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_CV_HANDLER(ZEND isset_no_object: result = ((opline->extended_value & ZEND_ISSET) == 0); } else { - result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); if ((opline->extended_value & ZEND_ISSET) == 0) { result = !result; } @@ -8177,7 +8177,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -8199,7 +8199,7 @@ fetch_obj_r_no_object: zend_error(E_NOTICE, "Trying to get property of non-object"); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -8243,7 +8243,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCOD if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -8265,7 +8265,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -8299,7 +8299,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMPVAR_HANDLER(ZEND if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); zval_ptr_dtor_nogc(free_op2); if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -8770,7 +8770,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMPVAR_HANDLER( isset_no_object: result = ((opline->extended_value & ZEND_ISSET) == 0); } else { - result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); if ((opline->extended_value & ZEND_ISSET) == 0) { result = !result; } @@ -9584,7 +9584,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HA if (IS_CONST == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -9606,7 +9606,7 @@ fetch_obj_r_no_object: zend_error(E_NOTICE, "Trying to get property of non-object"); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -9639,7 +9639,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OP if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -10664,7 +10664,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDL if (IS_CV == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -10686,7 +10686,7 @@ fetch_obj_r_no_object: zend_error(E_NOTICE, "Trying to get property of non-object"); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -10719,7 +10719,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCOD if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -11087,7 +11087,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_H if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -11109,7 +11109,7 @@ fetch_obj_r_no_object: zend_error(E_NOTICE, "Trying to get property of non-object"); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -11143,7 +11143,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMPVAR_HANDLER(ZEND_O if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); zval_ptr_dtor_nogc(free_op2); if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -12778,7 +12778,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -12792,7 +12792,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b zval rv; if (Z_OBJ_HT_P(object)->read_property && - (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { + (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) { zval rv; zval *value = Z_OBJ_HT_P(z)->get(z, &rv); @@ -12805,7 +12805,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b ZVAL_DEREF(z); SEPARATE_ZVAL_NOREF(z); binary_op(z, z, value); - Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), z); } @@ -13176,7 +13176,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -13189,7 +13189,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t zval rv; if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval rv; @@ -13206,7 +13206,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(retval, z); } - Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); @@ -13262,7 +13262,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_ /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); ZVAL_COPY_VALUE(retval, zptr); @@ -13272,7 +13272,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_ } else { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { zval rv; - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -13288,7 +13288,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_ ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); - Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(&z_copy); zval_ptr_dtor(z); } else { @@ -13444,7 +13444,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA if (IS_CONST == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -13466,7 +13466,7 @@ fetch_obj_r_no_object: zend_error(E_NOTICE, "Trying to get property of non-object"); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -13494,7 +13494,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -13518,7 +13518,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -13548,7 +13548,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -13574,7 +13574,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -13598,7 +13598,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_VAR, property_name, IS_CONST, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property_name)) : NULL)); + zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_VAR, property_name, IS_CONST, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_obj has two opcodes! */ @@ -14164,7 +14164,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } @@ -15659,7 +15659,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -15673,7 +15673,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina zval rv; if (Z_OBJ_HT_P(object)->read_property && - (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { + (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) { zval rv; zval *value = Z_OBJ_HT_P(z)->get(z, &rv); @@ -15686,7 +15686,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina ZVAL_DEREF(z); SEPARATE_ZVAL_NOREF(z); binary_op(z, z, value); - Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), z); } @@ -16057,7 +16057,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -16070,7 +16070,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in zval rv; if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval rv; @@ -16087,7 +16087,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(retval, z); } - Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); @@ -16143,7 +16143,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); ZVAL_COPY_VALUE(retval, zptr); @@ -16153,7 +16153,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i } else { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { zval rv; - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -16169,7 +16169,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); - Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(&z_copy); zval_ptr_dtor(z); } else { @@ -16325,7 +16325,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL if (IS_CV == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -16347,7 +16347,7 @@ fetch_obj_r_no_object: zend_error(E_NOTICE, "Trying to get property of non-object"); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -16375,7 +16375,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -16399,7 +16399,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -16429,7 +16429,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -16455,7 +16455,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -16479,7 +16479,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_VAR, property_name, IS_CV, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property_name)) : NULL)); + zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_VAR, property_name, IS_CV, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_obj has two opcodes! */ @@ -17001,7 +17001,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } @@ -17177,7 +17177,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMPVAR(int (* /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -17191,7 +17191,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMPVAR(int (* zval rv; if (Z_OBJ_HT_P(object)->read_property && - (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { + (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) { zval rv; zval *value = Z_OBJ_HT_P(z)->get(z, &rv); @@ -17204,7 +17204,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMPVAR(int (* ZVAL_DEREF(z); SEPARATE_ZVAL_NOREF(z); binary_op(z, z, value); - Z_OBJ_HT_P(object)->write_property(object, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), z); } @@ -17577,7 +17577,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMPVAR(incdec_ /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -17590,7 +17590,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMPVAR(incdec_ zval rv; if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval rv; @@ -17607,7 +17607,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMPVAR(incdec_ if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(retval, z); } - Z_OBJ_HT_P(object)->write_property(object, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); @@ -17664,7 +17664,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMPVAR(incdec /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); ZVAL_COPY_VALUE(retval, zptr); @@ -17674,7 +17674,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMPVAR(incdec } else { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { zval rv; - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -17690,7 +17690,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMPVAR(incdec ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); - Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(&z_copy); zval_ptr_dtor(z); } else { @@ -17847,7 +17847,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_H if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -17869,7 +17869,7 @@ fetch_obj_r_no_object: zend_error(E_NOTICE, "Trying to get property of non-object"); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -17898,7 +17898,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_H zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); zval_ptr_dtor_nogc(free_op2); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -17922,7 +17922,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_ if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); zval_ptr_dtor_nogc(free_op2); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -17952,7 +17952,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMPVAR_HANDLER(ZEND_O if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); zval_ptr_dtor_nogc(free_op2); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -17978,7 +17978,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCO if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); zval_ptr_dtor_nogc(free_op2); if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -18002,7 +18002,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HA if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_VAR, property_name, (IS_TMP_VAR|IS_VAR), (opline+1)->op1_type, (opline+1)->op1, execute_data, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property_name)) : NULL)); + zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_VAR, property_name, (IS_TMP_VAR|IS_VAR), (opline+1)->op1_type, (opline+1)->op1, execute_data, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); zval_ptr_dtor_nogc(free_op2); if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_obj has two opcodes! */ @@ -18438,7 +18438,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HAN } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } @@ -18580,7 +18580,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -18594,7 +18594,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int zval rv; if (Z_OBJ_HT_P(object)->read_property && - (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { + (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) { zval rv; zval *value = Z_OBJ_HT_P(z)->get(z, &rv); @@ -18607,7 +18607,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int ZVAL_DEREF(z); SEPARATE_ZVAL_NOREF(z); binary_op(z, z, value); - Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), z); } @@ -18943,7 +18943,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -18956,7 +18956,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde zval rv; if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval rv; @@ -18973,7 +18973,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(retval, z); } - Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); @@ -19029,7 +19029,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); ZVAL_COPY_VALUE(retval, zptr); @@ -19039,7 +19039,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd } else { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { zval rv; - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -19055,7 +19055,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); - Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(&z_copy); zval_ptr_dtor(z); } else { @@ -19110,7 +19110,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE if (IS_CONST == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -19132,7 +19132,7 @@ fetch_obj_r_no_object: zend_error(E_NOTICE, "Trying to get property of non-object"); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -19160,7 +19160,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -19184,7 +19184,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -19224,7 +19224,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD if (IS_CONST == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -19246,7 +19246,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -19279,7 +19279,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -19305,7 +19305,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OP if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -19329,7 +19329,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_ if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_UNUSED, property_name, IS_CONST, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property_name)) : NULL)); + zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_UNUSED, property_name, IS_CONST, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); /* assign_obj has two opcodes! */ @@ -19735,7 +19735,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_H } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } @@ -19890,7 +19890,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER( isset_no_object: result = ((opline->extended_value & ZEND_ISSET) == 0); } else { - result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); if ((opline->extended_value & ZEND_ISSET) == 0) { result = !result; } @@ -20785,7 +20785,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -20799,7 +20799,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b zval rv; if (Z_OBJ_HT_P(object)->read_property && - (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { + (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) { zval rv; zval *value = Z_OBJ_HT_P(z)->get(z, &rv); @@ -20812,7 +20812,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b ZVAL_DEREF(z); SEPARATE_ZVAL_NOREF(z); binary_op(z, z, value); - Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), z); } @@ -21148,7 +21148,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -21161,7 +21161,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t zval rv; if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval rv; @@ -21178,7 +21178,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(retval, z); } - Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); @@ -21234,7 +21234,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_ /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); ZVAL_COPY_VALUE(retval, zptr); @@ -21244,7 +21244,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_ } else { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { zval rv; - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -21260,7 +21260,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_ ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); - Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(&z_copy); zval_ptr_dtor(z); } else { @@ -21315,7 +21315,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA if (IS_CV == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -21337,7 +21337,7 @@ fetch_obj_r_no_object: zend_error(E_NOTICE, "Trying to get property of non-object"); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -21365,7 +21365,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -21389,7 +21389,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -21429,7 +21429,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H if (IS_CV == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -21451,7 +21451,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -21484,7 +21484,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OP if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -21510,7 +21510,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCOD if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -21534,7 +21534,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAN if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_UNUSED, property_name, IS_CV, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property_name)) : NULL)); + zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_UNUSED, property_name, IS_CV, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); /* assign_obj has two opcodes! */ @@ -21844,7 +21844,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } @@ -21999,7 +21999,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_HANDLER(ZEN isset_no_object: result = ((opline->extended_value & ZEND_ISSET) == 0); } else { - result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); if ((opline->extended_value & ZEND_ISSET) == 0) { result = !result; } @@ -22170,7 +22170,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMPVAR(int /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -22184,7 +22184,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMPVAR(int zval rv; if (Z_OBJ_HT_P(object)->read_property && - (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { + (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) { zval rv; zval *value = Z_OBJ_HT_P(z)->get(z, &rv); @@ -22197,7 +22197,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMPVAR(int ZVAL_DEREF(z); SEPARATE_ZVAL_NOREF(z); binary_op(z, z, value); - Z_OBJ_HT_P(object)->write_property(object, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), z); } @@ -22534,7 +22534,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMPVAR(incd /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -22547,7 +22547,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMPVAR(incd zval rv; if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval rv; @@ -22564,7 +22564,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMPVAR(incd if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(retval, z); } - Z_OBJ_HT_P(object)->write_property(object, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); @@ -22621,7 +22621,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMPVAR(inc /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); ZVAL_COPY_VALUE(retval, zptr); @@ -22631,7 +22631,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMPVAR(inc } else { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { zval rv; - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -22647,7 +22647,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMPVAR(inc ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); - Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(&z_copy); zval_ptr_dtor(z); } else { @@ -22703,7 +22703,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCOD if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -22725,7 +22725,7 @@ fetch_obj_r_no_object: zend_error(E_NOTICE, "Trying to get property of non-object"); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -22754,7 +22754,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCOD zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); zval_ptr_dtor_nogc(free_op2); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -22778,7 +22778,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCO if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); zval_ptr_dtor_nogc(free_op2); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -22818,7 +22818,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCO if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -22840,7 +22840,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -22874,7 +22874,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMPVAR_HANDLER(ZEN if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); zval_ptr_dtor_nogc(free_op2); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -22900,7 +22900,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_O if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); zval_ptr_dtor_nogc(free_op2); if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -22924,7 +22924,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_UNUSED, property_name, (IS_TMP_VAR|IS_VAR), (opline+1)->op1_type, (opline+1)->op1, execute_data, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property_name)) : NULL)); + zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_UNUSED, property_name, (IS_TMP_VAR|IS_VAR), (opline+1)->op1_type, (opline+1)->op1, execute_data, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); zval_ptr_dtor_nogc(free_op2); /* assign_obj has two opcodes! */ @@ -23236,7 +23236,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_ } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } @@ -23393,7 +23393,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMPVAR_HANDLER isset_no_object: result = ((opline->extended_value & ZEND_ISSET) == 0); } else { - result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); if ((opline->extended_value & ZEND_ISSET) == 0) { result = !result; } @@ -25230,7 +25230,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -25244,7 +25244,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi zval rv; if (Z_OBJ_HT_P(object)->read_property && - (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { + (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) { zval rv; zval *value = Z_OBJ_HT_P(z)->get(z, &rv); @@ -25257,7 +25257,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi ZVAL_DEREF(z); SEPARATE_ZVAL_NOREF(z); binary_op(z, z, value); - Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), z); } @@ -25628,7 +25628,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -25641,7 +25641,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t zval rv; if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval rv; @@ -25658,7 +25658,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(retval, z); } - Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); @@ -25714,7 +25714,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); ZVAL_COPY_VALUE(retval, zptr); @@ -25724,7 +25724,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t } else { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { zval rv; - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -25740,7 +25740,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); - Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(&z_copy); zval_ptr_dtor(z); } else { @@ -25793,7 +25793,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z if (IS_CV == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -26099,7 +26099,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN if (IS_CONST == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -26121,7 +26121,7 @@ fetch_obj_r_no_object: zend_error(E_NOTICE, "Trying to get property of non-object"); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -26149,7 +26149,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -26173,7 +26173,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -26213,7 +26213,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA if (IS_CONST == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -26235,7 +26235,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -26268,7 +26268,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -26294,7 +26294,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -26355,7 +26355,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_CV, property_name, IS_CONST, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property_name)) : NULL)); + zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_CV, property_name, IS_CONST, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); /* assign_obj has two opcodes! */ @@ -26905,7 +26905,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } @@ -26953,7 +26953,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCO if (IS_CV == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -27158,7 +27158,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CONST_HANDLER(ZEND isset_no_object: result = ((opline->extended_value & ZEND_ISSET) == 0); } else { - result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); if ((opline->extended_value & ZEND_ISSET) == 0) { result = !result; } @@ -27673,7 +27673,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN if (IS_CV == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -28017,7 +28017,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE if (IS_CV == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -28561,7 +28561,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type, if (IS_CV == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -29105,7 +29105,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPC if (IS_CV == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -29616,7 +29616,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -29630,7 +29630,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar zval rv; if (Z_OBJ_HT_P(object)->read_property && - (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { + (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) { zval rv; zval *value = Z_OBJ_HT_P(z)->get(z, &rv); @@ -29643,7 +29643,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar ZVAL_DEREF(z); SEPARATE_ZVAL_NOREF(z); binary_op(z, z, value); - Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), z); } @@ -30014,7 +30014,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -30027,7 +30027,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc zval rv; if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval rv; @@ -30044,7 +30044,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(retval, z); } - Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); @@ -30100,7 +30100,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); ZVAL_COPY_VALUE(retval, zptr); @@ -30110,7 +30110,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in } else { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { zval rv; - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -30126,7 +30126,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); - Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(&z_copy); zval_ptr_dtor(z); } else { @@ -30312,7 +30312,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE if (IS_CV == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -30334,7 +30334,7 @@ fetch_obj_r_no_object: zend_error(E_NOTICE, "Trying to get property of non-object"); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -30362,7 +30362,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -30386,7 +30386,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -30426,7 +30426,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL if (IS_CV == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -30448,7 +30448,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -30481,7 +30481,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -30507,7 +30507,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -30531,7 +30531,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_CV, property_name, IS_CV, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property_name)) : NULL)); + zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_CV, property_name, IS_CV, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); /* assign_obj has two opcodes! */ @@ -31059,7 +31059,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } @@ -31214,7 +31214,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_CV_HANDLER(ZEND_OP isset_no_object: result = ((opline->extended_value & ZEND_ISSET) == 0); } else { - result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); if ((opline->extended_value & ZEND_ISSET) == 0) { result = !result; } @@ -31665,7 +31665,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMPVAR(int (*b /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -31679,7 +31679,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMPVAR(int (*b zval rv; if (Z_OBJ_HT_P(object)->read_property && - (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { + (z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv)) != NULL) { if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) { zval rv; zval *value = Z_OBJ_HT_P(z)->get(z, &rv); @@ -31692,7 +31692,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMPVAR(int (*b ZVAL_DEREF(z); SEPARATE_ZVAL_NOREF(z); binary_op(z, z, value); - Z_OBJ_HT_P(object)->write_property(object, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(EX_VAR(opline->result.var), z); } @@ -32065,7 +32065,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMPVAR(incdec_t /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); SEPARATE_ZVAL_NOREF(zptr); @@ -32078,7 +32078,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMPVAR(incdec_t zval rv; if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { zval rv; @@ -32095,7 +32095,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMPVAR(incdec_t if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_COPY(retval, z); } - Z_OBJ_HT_P(object)->write_property(object, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, z, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(z); } else { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); @@ -32152,7 +32152,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMPVAR(incdec_ /* here we are sure we are dealing with an object */ if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { + && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL))) != NULL)) { ZVAL_DEREF(zptr); ZVAL_COPY_VALUE(retval, zptr); @@ -32162,7 +32162,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMPVAR(incdec_ } else { if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { zval rv; - zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv); + zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), &rv); zval z_copy; if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { @@ -32178,7 +32178,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMPVAR(incdec_ ZVAL_DUP(&z_copy, z); incdec_op(&z_copy); if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z); - Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL)); + Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL)); zval_ptr_dtor(&z_copy); zval_ptr_dtor(z); } else { @@ -32365,7 +32365,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HA if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -32387,7 +32387,7 @@ fetch_obj_r_no_object: zend_error(E_NOTICE, "Trying to get property of non-object"); ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -32416,7 +32416,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HA zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -32440,7 +32440,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_H if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW); zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -32480,7 +32480,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_H if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -32502,7 +32502,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -32536,7 +32536,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMPVAR_HANDLER(ZEND_OP if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W); zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -32562,7 +32562,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCOD if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET); zval_ptr_dtor_nogc(free_op2); if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); @@ -32586,7 +32586,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HAN if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } - zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_CV, property_name, (IS_TMP_VAR|IS_VAR), (opline+1)->op1_type, (opline+1)->op1, execute_data, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property_name)) : NULL)); + zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, IS_CV, property_name, (IS_TMP_VAR|IS_VAR), (opline+1)->op1_type, (opline+1)->op1, execute_data, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(property_name)) : NULL)); zval_ptr_dtor_nogc(free_op2); /* assign_obj has two opcodes! */ @@ -33031,7 +33031,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HAND } } if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); } else { zend_error(E_NOTICE, "Trying to unset property of non-object"); } @@ -33188,7 +33188,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMPVAR_HANDLER(ZEN isset_no_object: result = ((opline->extended_value & ZEND_ISSET) == 0); } else { - result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); if ((opline->extended_value & ZEND_ISSET) == 0) { result = !result; } @@ -34059,7 +34059,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMPVAR_CONST(int typ if ((IS_TMP_VAR|IS_VAR) == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -34265,7 +34265,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCOD if (IS_CONST == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -34287,7 +34287,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -34582,7 +34582,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_CONST_HANDLER(ZEND_ if ((IS_TMP_VAR|IS_VAR) == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -34788,7 +34788,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CONST_HANDLER( isset_no_object: result = ((opline->extended_value & ZEND_ISSET) == 0); } else { - result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CONST == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); if ((opline->extended_value & ZEND_ISSET) == 0) { result = !result; } @@ -34886,7 +34886,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMPVAR_VAR(int type, if ((IS_TMP_VAR|IS_VAR) == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -35144,7 +35144,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_VAR_HANDLER(ZEND_OP if ((IS_TMP_VAR|IS_VAR) == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -35277,7 +35277,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(int ty if ((IS_TMP_VAR|IS_VAR) == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + retval = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -35535,7 +35535,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMPVAR_UNUSED_HANDLER(ZEND if ((IS_TMP_VAR|IS_VAR) == IS_CONST && CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) { ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1))); - value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + 1); + value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)) + sizeof(void*)); /* check if static properties were destoyed */ if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) { @@ -35917,7 +35917,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_H if (IS_CV == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -35939,7 +35939,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -36229,7 +36229,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_CV_HANDLER(ZEN isset_no_object: result = ((opline->extended_value & ZEND_ISSET) == 0); } else { - result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((IS_CV == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); if ((opline->extended_value & ZEND_ISSET) == 0) { result = !result; } @@ -36576,7 +36576,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCO if ((IS_TMP_VAR|IS_VAR) == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { - uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); @@ -36598,7 +36598,7 @@ fetch_obj_is_no_object: ZVAL_NULL(EX_VAR(opline->result.var)); } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var)); if (retval != EX_VAR(opline->result.var)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -36892,7 +36892,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER isset_no_object: result = ((opline->extended_value & ZEND_ISSET) == 0); } else { - result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL)); + result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(Z_CACHE_SLOT_P(offset)) : NULL)); if ((opline->extended_value & ZEND_ISSET) == 0) { result = !result; } diff --git a/ext/opcache/Optimizer/compact_literals.c b/ext/opcache/Optimizer/compact_literals.c index 1ac7265e1c8..fd83e76461b 100644 --- a/ext/opcache/Optimizer/compact_literals.c +++ b/ext/opcache/Optimizer/compact_literals.c @@ -117,7 +117,7 @@ static void optimizer_literal_class_info(literal_info *info, void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx *ctx) { zend_op *opline, *end; - int i, j, n, *map, cache_slots; + int i, j, n, *map, cache_size; zval zv, *pos; literal_info *info; int l_null = -1; @@ -318,7 +318,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx #endif /* Merge equal constants */ - j = 0; cache_slots = 0; + j = 0; cache_size = 0; zend_hash_init(&hash, op_array->last_literal, NULL, NULL, 0); map = (int*)zend_arena_alloc(&ctx->arena, op_array->last_literal * sizeof(int)); memset(map, 0, op_array->last_literal * sizeof(int)); @@ -439,8 +439,8 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx info[j] = info[i]; } if (LITERAL_NUM_SLOTS(info[i].flags)) { - Z_CACHE_SLOT(op_array->literals[j]) = cache_slots; - cache_slots += LITERAL_NUM_SLOTS(info[i].flags); + Z_CACHE_SLOT(op_array->literals[j]) = cache_size; + cache_size += LITERAL_NUM_SLOTS(info[i].flags) * sizeof(void*); } j++; n = LITERAL_NUM_RELATED(info[i].flags); @@ -465,7 +465,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx } zend_hash_destroy(&hash); op_array->last_literal = j; - op_array->last_cache_slot = cache_slots; + op_array->cache_size = cache_size; /* Update opcodes to use new literals table */ opline = op_array->opcodes; diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index eab51c7f66f..c9ee97f49d1 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -129,7 +129,8 @@ void zend_optimizer_update_op1_const(zend_op_array *op_array, case ZEND_NEW: opline->op1.constant = zend_optimizer_add_literal(op_array, val); zend_string_hash_val(Z_STR(ZEND_OP1_LITERAL(opline))); - Z_CACHE_SLOT(op_array->literals[opline->op1.constant]) = op_array->last_cache_slot++; + Z_CACHE_SLOT(op_array->literals[opline->op1.constant]) = op_array->cache_size; + op_array->cache_size += sizeof(void*); zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); zend_optimizer_add_literal(op_array, val); zend_string_hash_val(Z_STR(op_array->literals[opline->op1.constant+1])); @@ -154,7 +155,8 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array, zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); opline->op2.constant = zend_optimizer_add_literal(op_array, val); zend_string_hash_val(Z_STR(ZEND_OP2_LITERAL(opline))); - Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot++; + Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size; + op_array->cache_size += sizeof(void*); return; } opline->op2.constant = zend_optimizer_add_literal(op_array, val); @@ -175,14 +177,16 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array, case ZEND_ADD_INTERFACE: case ZEND_ADD_TRAIT: case ZEND_INSTANCEOF: - Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot++; + Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size; + op_array->cache_size += sizeof(void*); zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); zend_optimizer_add_literal(op_array, val); zend_string_hash_val(Z_STR(op_array->literals[opline->op2.constant+1])); break; case ZEND_INIT_DYNAMIC_CALL: opline->opcode = ZEND_INIT_FCALL_BY_NAME; - Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot++; + Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size; + op_array->cache_size += sizeof(void*); zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val)); zend_optimizer_add_literal(op_array, val); zend_string_hash_val(Z_STR(op_array->literals[opline->op2.constant+1])); @@ -207,8 +211,8 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array, case ZEND_POST_INC_OBJ: case ZEND_POST_DEC_OBJ: case ZEND_ISSET_ISEMPTY_PROP_OBJ: - Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot; - op_array->last_cache_slot += 2; + Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size; + op_array->cache_size += 2 * sizeof(void*); break; case ZEND_ASSIGN_ADD: case ZEND_ASSIGN_SUB: @@ -222,8 +226,8 @@ void zend_optimizer_update_op2_const(zend_op_array *op_array, case ZEND_ASSIGN_BW_AND: case ZEND_ASSIGN_BW_XOR: if (opline->extended_value == ZEND_ASSIGN_OBJ) { - Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->last_cache_slot; - op_array->last_cache_slot += 2; + Z_CACHE_SLOT(op_array->literals[opline->op2.constant]) = op_array->cache_size; + op_array->cache_size += 2 * sizeof(void*); } break; case ZEND_OP_DATA: From c2c78dc963a3360035dfaca417fa3351bd6c5e1f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 25 Feb 2015 10:37:21 +0300 Subject: [PATCH 50/59] Added specialized versions of DO_FCALL handler: DO_ICALL - for internal functions DO_UCALL - for user functions DO_FCALL_BY_NAME - plain, most probably user, funcstions (not methods) --- Zend/zend_builtin_functions.c | 6 + Zend/zend_compile.c | 27 +- Zend/zend_compile.h | 1 + Zend/zend_execute.c | 6 +- Zend/zend_execute_API.c | 5 +- Zend/zend_vm_def.h | 193 +++++++++- Zend/zend_vm_execute.h | 383 +++++++++++++++----- Zend/zend_vm_opcodes.c | 6 +- Zend/zend_vm_opcodes.h | 3 + ext/opcache/Optimizer/block_pass.c | 3 + ext/opcache/Optimizer/optimize_func_calls.c | 5 + ext/opcache/Optimizer/pass1_5.c | 2 +- ext/opcache/ZendAccelerator.c | 18 +- sapi/phpdbg/phpdbg_prompt.c | 5 +- 14 files changed, 555 insertions(+), 108 deletions(-) diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 035a4c6c886..195d9c2509f 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -2258,6 +2258,9 @@ ZEND_FUNCTION(debug_print_backtrace) skip->prev_execute_data->func && ZEND_USER_CODE(skip->prev_execute_data->func->common.type) && skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL && + skip->prev_execute_data->opline->opcode != ZEND_DO_ICALL && + skip->prev_execute_data->opline->opcode != ZEND_DO_UCALL && + skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME && skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) { skip = skip->prev_execute_data; } @@ -2453,6 +2456,9 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int skip->prev_execute_data->func && ZEND_USER_CODE(skip->prev_execute_data->func->common.type) && skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL && + skip->prev_execute_data->opline->opcode != ZEND_DO_ICALL && + skip->prev_execute_data->opline->opcode != ZEND_DO_UCALL && + skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME && skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) { skip = skip->prev_execute_data; } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 9fbfa1f82f8..1a716080838 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2617,6 +2617,31 @@ uint32_t zend_compile_args(zend_ast *ast, zend_function *fbc) /* {{{ */ } /* }}} */ +ZEND_API zend_uchar zend_get_call_op(zend_uchar init_op, zend_function *fbc) /* {{{ */ +{ + if (fbc) { + if (fbc->type == ZEND_INTERNAL_FUNCTION) { + if (!zend_execute_internal && + !fbc->common.scope && + !(fbc->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED|ZEND_ACC_HAS_TYPE_HINTS))) { + return ZEND_DO_ICALL; + } + } else { + if (zend_execute_ex == execute_ex && + !(fbc->common.fn_flags & ZEND_ACC_GENERATOR)) { + return ZEND_DO_UCALL; + } + } + } else if (zend_execute_ex == execute_ex && + !zend_execute_internal && + (init_op == ZEND_INIT_FCALL_BY_NAME || + init_op == ZEND_INIT_NS_FCALL_BY_NAME)) { + return ZEND_DO_FCALL_BY_NAME; + } + return ZEND_DO_FCALL; +} +/* }}} */ + void zend_compile_call_common(znode *result, zend_ast *args_ast, zend_function *fbc) /* {{{ */ { zend_op *opline; @@ -2636,7 +2661,7 @@ void zend_compile_call_common(znode *result, zend_ast *args_ast, zend_function * } call_flags = (opline->opcode == ZEND_NEW ? ZEND_CALL_CTOR : 0); - opline = zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL); + opline = zend_emit_op(result, zend_get_call_op(opline->opcode, fbc), NULL, NULL); opline->op1.num = call_flags; zend_do_extended_fcall_end(); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 6073e240f32..8e4148795e8 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -718,6 +718,7 @@ ZEND_API zend_bool zend_is_compiling(void); ZEND_API char *zend_make_compiled_string_description(const char *name); ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers); uint32_t zend_get_class_fetch_type(zend_string *name); +ZEND_API zend_uchar zend_get_call_op(zend_uchar init_op, zend_function *fbc); typedef zend_bool (*zend_auto_global_callback)(zend_string *name); typedef struct _zend_auto_global { diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index b016df1e252..0cf2f2c53eb 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1742,7 +1742,7 @@ void zend_free_compiled_variables(zend_execute_data *execute_data) /* {{{ */ * +----------------------------------------+ */ -static zend_always_inline void i_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */ +static zend_always_inline void i_init_func_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value, int check_this) /* {{{ */ { uint32_t first_extra_arg, num_args; ZEND_ASSERT(EX(func) == (zend_function*)op_array); @@ -1798,7 +1798,7 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu } while (var != end); } - if (op_array->this_var != (uint32_t)-1 && EXPECTED(Z_OBJ(EX(This)))) { + if (check_this && op_array->this_var != (uint32_t)-1 && EXPECTED(Z_OBJ(EX(This)))) { ZVAL_OBJ(EX_VAR(op_array->this_var), Z_OBJ(EX(This))); GC_REFCOUNT(Z_OBJ(EX(This)))++; } @@ -1966,7 +1966,7 @@ ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_execute_data EX(symbol_table) = NULL; - i_init_func_execute_data(execute_data, op_array, return_value); + i_init_func_execute_data(execute_data, op_array, return_value, 1); return execute_data; } diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index fc94beeb7fc..f52d9f33ce4 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -691,7 +691,10 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / EG(current_execute_data) = &dummy_execute_data; } else if (EG(current_execute_data)->func && ZEND_USER_CODE(EG(current_execute_data)->func->common.type) && - EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL) { + EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL && + EG(current_execute_data)->opline->opcode != ZEND_DO_ICALL && + EG(current_execute_data)->opline->opcode != ZEND_DO_UCALL && + EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL_BY_NAME) { /* Insert fake frame in case of include or magic calls */ dummy_execute_data = *EG(current_execute_data); dummy_execute_data.prev_execute_data = EG(current_execute_data); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 8e2051e6c0a..04b1d1d6962 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2354,7 +2354,10 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMPVAR|UNUSED|CV, CONST|TMPVAR|CV) opline->opcode == ZEND_NEW ) { nesting++; - } else if (opline->opcode == ZEND_DO_FCALL) { + } else if (opline->opcode == ZEND_DO_FCALL || + opline->opcode == ZEND_DO_ICALL || + opline->opcode == ZEND_DO_UCALL || + opline->opcode == ZEND_DO_FCALL_BY_NAME) { nesting--; } } while (nesting); @@ -2796,6 +2799,185 @@ ZEND_VM_HANDLER(61, ZEND_INIT_FCALL, ANY, CONST) ZEND_VM_NEXT_OPCODE(); } +ZEND_VM_HANDLER(129, ZEND_DO_ICALL, ANY, ANY) +{ + USE_OPLINE + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; + + SAVE_OPLINE(); + EX(call) = call->prev_execute_data; + + LOAD_OPLINE(); + + call->called_scope = EX(called_scope); + Z_OBJ(call->This) = Z_OBJ(EX(This)); + + call->prev_execute_data = execute_data; + EG(current_execute_data) = call; + + ret = EX_VAR(opline->result.var); + ZVAL_NULL(ret); + Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0; + + fbc->internal_function.handler(call, ret); + + ZEND_ASSERT( + !call->func || + !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var))); + + EG(current_execute_data) = call->prev_execute_data; + zend_vm_stack_free_args(call); + zend_vm_stack_free_call_frame(call); + + if (!RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(EX_VAR(opline->result.var)); + } + + if (UNEXPECTED(EG(exception) != NULL)) { + zend_throw_exception_internal(NULL); + if (RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(EX_VAR(opline->result.var)); + } + HANDLE_EXCEPTION(); + } + + ZEND_VM_NEXT_OPCODE(); +} + +ZEND_VM_HANDLER(130, ZEND_DO_UCALL, ANY, ANY) +{ + USE_OPLINE + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; + + SAVE_OPLINE(); + EX(call) = call->prev_execute_data; + + LOAD_OPLINE(); + + EG(scope) = NULL; + ret = NULL; + call->symbol_table = NULL; + if (RETURN_VALUE_USED(opline)) { + ret = EX_VAR(opline->result.var); + ZVAL_NULL(ret); + Z_VAR_FLAGS_P(ret) = 0; + } + + call->prev_execute_data = execute_data; + i_init_func_execute_data(call, &fbc->op_array, ret, 0); + + ZEND_VM_ENTER(); +} + +ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY) +{ + USE_OPLINE + zend_execute_data *call = EX(call); + zend_function *fbc = call->func; + zval *ret; + + SAVE_OPLINE(); + EX(call) = call->prev_execute_data; + + LOAD_OPLINE(); + + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { + EG(scope) = NULL; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) { + if (RETURN_VALUE_USED(opline)) { + zend_generator_create_zval(call, &fbc->op_array, EX_VAR(opline->result.var)); + } else { + zend_vm_stack_free_args(call); + } + + zend_vm_stack_free_call_frame(call); + } else { + ret = NULL; + call->symbol_table = NULL; + if (RETURN_VALUE_USED(opline)) { + ret = EX_VAR(opline->result.var); + ZVAL_NULL(ret); + Z_VAR_FLAGS_P(ret) = 0; + } + + call->prev_execute_data = execute_data; + i_init_func_execute_data(call, &fbc->op_array, ret, 0); + + ZEND_VM_ENTER(); + } + EG(scope) = EX(func)->op_array.scope; + } else { + ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); + + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) { + zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated", + fbc->common.scope ? fbc->common.scope->name->val : "", + fbc->common.scope ? "::" : "", + fbc->common.function_name->val); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + + call->called_scope = EX(called_scope); + Z_OBJ(call->This) = Z_OBJ(EX(This)); + + call->prev_execute_data = execute_data; + EG(current_execute_data) = call; + + if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) { + uint32_t i; + uint32_t num_args = ZEND_CALL_NUM_ARGS(call); + zval *p = ZEND_CALL_ARG(call, 1); + + for (i = 0; i < num_args; ++i) { + zend_verify_internal_arg_type(fbc, i + 1, p); + p++; + } + if (UNEXPECTED(EG(exception) != NULL)) { + EG(current_execute_data) = call->prev_execute_data; + zend_vm_stack_free_args(call); + zend_vm_stack_free_call_frame(call); + zend_throw_exception_internal(NULL); + HANDLE_EXCEPTION(); + } + } + + ret = EX_VAR(opline->result.var); + ZVAL_NULL(ret); + Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0; + + fbc->internal_function.handler(call, ret); + + ZEND_ASSERT( + !call->func || + !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var))); + + EG(current_execute_data) = call->prev_execute_data; + zend_vm_stack_free_args(call); + zend_vm_stack_free_call_frame(call); + + if (!RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(EX_VAR(opline->result.var)); + } + } + + if (UNEXPECTED(EG(exception) != NULL)) { + zend_throw_exception_internal(NULL); + if (RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(EX_VAR(opline->result.var)); + } + HANDLE_EXCEPTION(); + } + ZEND_VM_NEXT_OPCODE(); +} + ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY) { USE_OPLINE @@ -2843,7 +3025,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY) } call->prev_execute_data = execute_data; - i_init_func_execute_data(call, &fbc->op_array, ret); + i_init_func_execute_data(call, &fbc->op_array, ret, 1); if (EXPECTED(zend_execute_ex == execute_ex)) { ZEND_VM_ENTER(); @@ -2854,7 +3036,6 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY) } } else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) { int should_change_scope = 0; - zval *ret; if (fbc->common.scope) { should_change_scope = 1; @@ -5965,6 +6146,9 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) do { switch (opline->opcode) { case ZEND_DO_FCALL: + case ZEND_DO_ICALL: + case ZEND_DO_UCALL: + case ZEND_DO_FCALL_BY_NAME: level++; break; case ZEND_INIT_FCALL: @@ -6011,6 +6195,9 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) do { switch (opline->opcode) { case ZEND_DO_FCALL: + case ZEND_DO_ICALL: + case ZEND_DO_UCALL: + case ZEND_DO_FCALL_BY_NAME: level++; break; case ZEND_INIT_FCALL: diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 04a8787262d..d4e29353fc1 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -486,6 +486,185 @@ static int ZEND_FASTCALL ZEND_JMP_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) ZEND_VM_CONTINUE(); } +static int ZEND_FASTCALL ZEND_DO_ICALL_SPEC_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; + + LOAD_OPLINE(); + + call->called_scope = EX(called_scope); + Z_OBJ(call->This) = Z_OBJ(EX(This)); + + call->prev_execute_data = execute_data; + EG(current_execute_data) = call; + + ret = EX_VAR(opline->result.var); + ZVAL_NULL(ret); + Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0; + + fbc->internal_function.handler(call, ret); + + ZEND_ASSERT( + !call->func || + !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var))); + + EG(current_execute_data) = call->prev_execute_data; + zend_vm_stack_free_args(call); + zend_vm_stack_free_call_frame(call); + + if (!RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(EX_VAR(opline->result.var)); + } + + if (UNEXPECTED(EG(exception) != NULL)) { + zend_throw_exception_internal(NULL); + if (RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(EX_VAR(opline->result.var)); + } + HANDLE_EXCEPTION(); + } + + ZEND_VM_NEXT_OPCODE(); +} + +static int ZEND_FASTCALL ZEND_DO_UCALL_SPEC_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; + + LOAD_OPLINE(); + + EG(scope) = NULL; + ret = NULL; + call->symbol_table = NULL; + if (RETURN_VALUE_USED(opline)) { + ret = EX_VAR(opline->result.var); + ZVAL_NULL(ret); + Z_VAR_FLAGS_P(ret) = 0; + } + + call->prev_execute_data = execute_data; + i_init_func_execute_data(call, &fbc->op_array, ret, 0); + + ZEND_VM_ENTER(); +} + +static int ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_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; + + LOAD_OPLINE(); + + if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) { + EG(scope) = NULL; + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) { + if (RETURN_VALUE_USED(opline)) { + zend_generator_create_zval(call, &fbc->op_array, EX_VAR(opline->result.var)); + } else { + zend_vm_stack_free_args(call); + } + + zend_vm_stack_free_call_frame(call); + } else { + ret = NULL; + call->symbol_table = NULL; + if (RETURN_VALUE_USED(opline)) { + ret = EX_VAR(opline->result.var); + ZVAL_NULL(ret); + Z_VAR_FLAGS_P(ret) = 0; + } + + call->prev_execute_data = execute_data; + i_init_func_execute_data(call, &fbc->op_array, ret, 0); + + ZEND_VM_ENTER(); + } + EG(scope) = EX(func)->op_array.scope; + } else { + ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION); + + if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_DEPRECATED) != 0)) { + zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated", + fbc->common.scope ? fbc->common.scope->name->val : "", + fbc->common.scope ? "::" : "", + fbc->common.function_name->val); + if (UNEXPECTED(EG(exception) != NULL)) { + HANDLE_EXCEPTION(); + } + } + + call->called_scope = EX(called_scope); + Z_OBJ(call->This) = Z_OBJ(EX(This)); + + call->prev_execute_data = execute_data; + EG(current_execute_data) = call; + + if (fbc->common.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) { + uint32_t i; + uint32_t num_args = ZEND_CALL_NUM_ARGS(call); + zval *p = ZEND_CALL_ARG(call, 1); + + for (i = 0; i < num_args; ++i) { + zend_verify_internal_arg_type(fbc, i + 1, p); + p++; + } + if (UNEXPECTED(EG(exception) != NULL)) { + EG(current_execute_data) = call->prev_execute_data; + zend_vm_stack_free_args(call); + zend_vm_stack_free_call_frame(call); + zend_throw_exception_internal(NULL); + HANDLE_EXCEPTION(); + } + } + + ret = EX_VAR(opline->result.var); + ZVAL_NULL(ret); + Z_VAR_FLAGS_P(ret) = (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0 ? IS_VAR_RET_REF : 0; + + fbc->internal_function.handler(call, ret); + + ZEND_ASSERT( + !call->func || + !(call->func->common.fn_flags & ZEND_ACC_HAS_RETURN_TYPE) || + zend_verify_internal_return_type(call->func, EX_VAR(opline->result.var))); + + EG(current_execute_data) = call->prev_execute_data; + zend_vm_stack_free_args(call); + zend_vm_stack_free_call_frame(call); + + if (!RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(EX_VAR(opline->result.var)); + } + } + + if (UNEXPECTED(EG(exception) != NULL)) { + zend_throw_exception_internal(NULL); + if (RETURN_VALUE_USED(opline)) { + zval_ptr_dtor(EX_VAR(opline->result.var)); + } + HANDLE_EXCEPTION(); + } + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { USE_OPLINE @@ -533,7 +712,7 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } call->prev_execute_data = execute_data; - i_init_func_execute_data(call, &fbc->op_array, ret); + i_init_func_execute_data(call, &fbc->op_array, ret, 1); if (EXPECTED(zend_execute_ex == execute_ex)) { ZEND_VM_ENTER(); @@ -544,7 +723,6 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } } else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) { int should_change_scope = 0; - zval *ret; if (fbc->common.scope) { should_change_scope = 1; @@ -1255,6 +1433,9 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER do { switch (opline->opcode) { case ZEND_DO_FCALL: + case ZEND_DO_ICALL: + case ZEND_DO_UCALL: + case ZEND_DO_FCALL_BY_NAME: level++; break; case ZEND_INIT_FCALL: @@ -1301,6 +1482,9 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER do { switch (opline->opcode) { case ZEND_DO_FCALL: + case ZEND_DO_ICALL: + case ZEND_DO_UCALL: + case ZEND_DO_FCALL_BY_NAME: level++; break; case ZEND_INIT_FCALL: @@ -19437,7 +19621,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O opline->opcode == ZEND_NEW ) { nesting++; - } else if (opline->opcode == ZEND_DO_FCALL) { + } else if (opline->opcode == ZEND_DO_FCALL || + opline->opcode == ZEND_DO_ICALL || + opline->opcode == ZEND_DO_UCALL || + opline->opcode == ZEND_DO_FCALL_BY_NAME) { nesting--; } } while (nesting); @@ -21644,7 +21831,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO opline->opcode == ZEND_NEW ) { nesting++; - } else if (opline->opcode == ZEND_DO_FCALL) { + } else if (opline->opcode == ZEND_DO_FCALL || + opline->opcode == ZEND_DO_ICALL || + opline->opcode == ZEND_DO_UCALL || + opline->opcode == ZEND_DO_FCALL_BY_NAME) { nesting--; } } while (nesting); @@ -23035,7 +23225,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_ opline->opcode == ZEND_NEW ) { nesting++; - } else if (opline->opcode == ZEND_DO_FCALL) { + } else if (opline->opcode == ZEND_DO_FCALL || + opline->opcode == ZEND_DO_ICALL || + opline->opcode == ZEND_DO_UCALL || + opline->opcode == ZEND_DO_FCALL_BY_NAME) { nesting--; } } while (nesting); @@ -26527,7 +26720,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD opline->opcode == ZEND_NEW ) { nesting++; - } else if (opline->opcode == ZEND_DO_FCALL) { + } else if (opline->opcode == ZEND_DO_FCALL || + opline->opcode == ZEND_DO_ICALL || + opline->opcode == ZEND_DO_UCALL || + opline->opcode == ZEND_DO_FCALL_BY_NAME) { nesting--; } } while (nesting); @@ -30756,7 +30952,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H opline->opcode == ZEND_NEW ) { nesting++; - } else if (opline->opcode == ZEND_DO_FCALL) { + } else if (opline->opcode == ZEND_DO_FCALL || + opline->opcode == ZEND_DO_ICALL || + opline->opcode == ZEND_DO_UCALL || + opline->opcode == ZEND_DO_FCALL_BY_NAME) { nesting--; } } while (nesting); @@ -32726,7 +32925,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCO opline->opcode == ZEND_NEW ) { nesting++; - } else if (opline->opcode == ZEND_DO_FCALL) { + } else if (opline->opcode == ZEND_DO_FCALL || + opline->opcode == ZEND_DO_ICALL || + opline->opcode == ZEND_DO_UCALL || + opline->opcode == ZEND_DO_FCALL_BY_NAME) { nesting--; } } while (nesting); @@ -34399,7 +34601,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CONST_HANDLER(ZEND_O opline->opcode == ZEND_NEW ) { nesting++; - } else if (opline->opcode == ZEND_DO_FCALL) { + } else if (opline->opcode == ZEND_DO_FCALL || + opline->opcode == ZEND_DO_ICALL || + opline->opcode == ZEND_DO_UCALL || + opline->opcode == ZEND_DO_FCALL_BY_NAME) { nesting--; } } while (nesting); @@ -36014,7 +36219,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCO opline->opcode == ZEND_NEW ) { nesting++; - } else if (opline->opcode == ZEND_DO_FCALL) { + } else if (opline->opcode == ZEND_DO_FCALL || + opline->opcode == ZEND_DO_ICALL || + opline->opcode == ZEND_DO_UCALL || + opline->opcode == ZEND_DO_FCALL_BY_NAME) { nesting--; } } while (nesting); @@ -36674,7 +36882,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_ opline->opcode == ZEND_NEW ) { nesting++; - } else if (opline->opcode == ZEND_DO_FCALL) { + } else if (opline->opcode == ZEND_DO_FCALL || + opline->opcode == ZEND_DO_ICALL || + opline->opcode == ZEND_DO_UCALL || + opline->opcode == ZEND_DO_FCALL_BY_NAME) { nesting--; } } while (nesting); @@ -40155,81 +40366,81 @@ void zend_init_opcodes_handlers(void) ZEND_INIT_DYNAMIC_CALL_SPEC_TMPVAR_HANDLER, ZEND_NULL_HANDLER, ZEND_INIT_DYNAMIC_CALL_SPEC_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_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_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_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_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_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_ICALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_UCALL_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, + ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, ZEND_NULL_HANDLER, diff --git a/Zend/zend_vm_opcodes.c b/Zend/zend_vm_opcodes.c index 1ab2a9e0fa0..991e56bc77a 100644 --- a/Zend/zend_vm_opcodes.c +++ b/Zend/zend_vm_opcodes.c @@ -151,9 +151,9 @@ const char *zend_vm_opcodes_map[171] = { "ZEND_FE_FETCH_RW", "ZEND_FE_FREE", "ZEND_INIT_DYNAMIC_CALL", - NULL, - NULL, - NULL, + "ZEND_DO_ICALL", + "ZEND_DO_UCALL", + "ZEND_DO_FCALL_BY_NAME", "ZEND_PRE_INC_OBJ", "ZEND_PRE_DEC_OBJ", "ZEND_POST_INC_OBJ", diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index d21ff08e7f9..367e52150c0 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -153,6 +153,9 @@ END_EXTERN_C() #define ZEND_FE_FETCH_RW 126 #define ZEND_FE_FREE 127 #define ZEND_INIT_DYNAMIC_CALL 128 +#define ZEND_DO_ICALL 129 +#define ZEND_DO_UCALL 130 +#define ZEND_DO_FCALL_BY_NAME 131 #define ZEND_PRE_INC_OBJ 132 #define ZEND_PRE_DEC_OBJ 133 #define ZEND_POST_INC_OBJ 134 diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 4db48944e17..0922d6e8098 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -1828,6 +1828,9 @@ static void zend_t_usage(zend_code_block *block, zend_op_array *op_array, char * case ZEND_ASSIGN: case ZEND_ASSIGN_REF: case ZEND_DO_FCALL: + case ZEND_DO_ICALL: + case ZEND_DO_UCALL: + case ZEND_DO_FCALL_BY_NAME: if (ZEND_RESULT_TYPE(opline) == IS_VAR) { ZEND_RESULT_TYPE(opline) |= EXT_TYPE_UNUSED; } diff --git a/ext/opcache/Optimizer/optimize_func_calls.c b/ext/opcache/Optimizer/optimize_func_calls.c index a83adab5ec1..270e38d5948 100644 --- a/ext/opcache/Optimizer/optimize_func_calls.c +++ b/ext/opcache/Optimizer/optimize_func_calls.c @@ -75,6 +75,9 @@ void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) call++; break; case ZEND_DO_FCALL: + case ZEND_DO_ICALL: + case ZEND_DO_UCALL: + case ZEND_DO_FCALL_BY_NAME: call--; if (call_stack[call].func && call_stack[call].opline) { zend_op *fcall = call_stack[call].opline; @@ -85,6 +88,7 @@ void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) Z_CACHE_SLOT(op_array->literals[fcall->op2.constant + 1]) = Z_CACHE_SLOT(op_array->literals[fcall->op2.constant]); literal_dtor(&ZEND_OP2_LITERAL(fcall)); fcall->op2.constant = fcall->op2.constant + 1; + opline->opcode = zend_get_call_op(ZEND_INIT_FCALL, call_stack[call].func); } else if (fcall->opcode == ZEND_INIT_NS_FCALL_BY_NAME) { fcall->opcode = ZEND_INIT_FCALL; fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func); @@ -92,6 +96,7 @@ void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx) literal_dtor(&op_array->literals[fcall->op2.constant]); literal_dtor(&op_array->literals[fcall->op2.constant + 2]); fcall->op2.constant = fcall->op2.constant + 1; + opline->opcode = zend_get_call_op(ZEND_INIT_FCALL, call_stack[call].func); } else { ZEND_ASSERT(0); } diff --git a/ext/opcache/Optimizer/pass1_5.c b/ext/opcache/Optimizer/pass1_5.c index 341e80501b4..990b845d434 100644 --- a/ext/opcache/Optimizer/pass1_5.c +++ b/ext/opcache/Optimizer/pass1_5.c @@ -341,7 +341,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) } break; - case ZEND_DO_FCALL: { + case ZEND_DO_ICALL: { zend_op *send1_opline = opline - 1; zend_op *send2_opline = NULL; zend_op *init_opline = NULL; diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index cdcbfeda560..3aa90fb7386 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -1836,6 +1836,11 @@ static void accel_activate(void) return; } + if (!ZCG(function_table).nTableSize) { + zend_hash_init(&ZCG(function_table), zend_hash_num_elements(CG(function_table)), NULL, ZEND_FUNCTION_DTOR, 1); + zend_accel_copy_internal_functions(); + } + SHM_UNPROTECT(); /* PHP-5.4 and above return "double", but we use 1 sec precision */ ZCG(auto_globals_mask) = 0; @@ -2257,8 +2262,6 @@ static void accel_globals_ctor(zend_accel_globals *accel_globals) ZEND_TSRMLS_CACHE_UPDATE(); #endif memset(accel_globals, 0, sizeof(zend_accel_globals)); - zend_hash_init(&accel_globals->function_table, zend_hash_num_elements(CG(function_table)), NULL, ZEND_FUNCTION_DTOR, 1); - zend_accel_copy_internal_functions(); } static void accel_globals_internal_func_dtor(zval *zv) @@ -2268,8 +2271,10 @@ static void accel_globals_internal_func_dtor(zval *zv) static void accel_globals_dtor(zend_accel_globals *accel_globals) { - accel_globals->function_table.pDestructor = accel_globals_internal_func_dtor; - zend_hash_destroy(&accel_globals->function_table); + if (accel_globals->function_table.nTableSize) { + accel_globals->function_table.pDestructor = accel_globals_internal_func_dtor; + zend_hash_destroy(&accel_globals->function_table); + } } static int accel_startup(zend_extension *extension) @@ -2422,11 +2427,6 @@ static int accel_startup(zend_extension *extension) zend_accel_blacklist_load(&accel_blacklist, ZCG(accel_directives.user_blacklist_filename)); } -#if 0 - /* FIXME: We probably don't need it here */ - zend_accel_copy_internal_functions(); -#endif - return SUCCESS; } diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index 6e492b7aaa4..72cb2e018c4 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -1454,7 +1454,10 @@ next: PHPDBG_G(last_line) = execute_data->opline->lineno; /* stupid hack to make zend_do_fcall_common_helper return ZEND_VM_ENTER() instead of recursively calling zend_execute() and eventually segfaulting */ - if (execute_data->opline->opcode == ZEND_DO_FCALL && execute_data->func->type == ZEND_USER_FUNCTION) { + if ((execute_data->opline->opcode == ZEND_DO_FCALL || + execute_data->opline->opcode == ZEND_DO_UCALL || + execute_data->opline->opcode == ZEND_DO_FCALL_BY_NAME) && + execute_data->func->type == ZEND_USER_FUNCTION) { zend_execute_ex = execute_ex; } PHPDBG_G(vmret) = execute_data->opline->handler(execute_data); From ffdc5728c8d0c1cc31e2a13d1d7a03e85a85e7f0 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 25 Feb 2015 18:21:59 +0800 Subject: [PATCH 51/59] Fixed bug #69108 ("Segmentation fault" when (de)serializing SplObjectStorage) --- NEWS | 2 ++ ext/spl/spl_observer.c | 1 + ext/spl/tests/bug69108.phpt | 22 ++++++++++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 ext/spl/tests/bug69108.phpt diff --git a/NEWS b/NEWS index ef42a5e32ec..f8d653fd5b2 100644 --- a/NEWS +++ b/NEWS @@ -36,6 +36,8 @@ PHP NEWS parameters). (Laruence) - SPL: + . Fixed bug #69108 ("Segmentation fault" when (de)serializing + SplObjectStorage). (Laruence) . Fixed bug #68557 (RecursiveDirectoryIterator::seek(0) broken after calling getChildren()). (Julien) diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index a7f61327472..5e210888918 100644 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -782,6 +782,7 @@ SPL_METHOD(SplObjectStorage, serialize) INIT_PZVAL(&members); Z_ARRVAL(members) = zend_std_get_properties(getThis() TSRMLS_CC); Z_TYPE(members) = IS_ARRAY; + zend_hash_del(Z_ARRVAL(members), "\x00gcdata", sizeof("\x00gcdata")); pmembers = &members; php_var_serialize(&buf, &pmembers, &var_hash TSRMLS_CC); /* finishes the string */ diff --git a/ext/spl/tests/bug69108.phpt b/ext/spl/tests/bug69108.phpt new file mode 100644 index 00000000000..1829e9b2a25 --- /dev/null +++ b/ext/spl/tests/bug69108.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #69108 ("Segmentation fault" when (de)serializing SplObjectStorage) +--INI-- +zend.enable_gc=1 +--FILE-- + 0; $i--) { + $object = new StdClass(); + $a[] = $object; + $b->attach($object); +} + +$c = serialize(array($a, $b)); +$d = unserialize($c); + +unset($d); +echo "ok"; +?> +--EXPECT-- +ok From d05575afd032b199e43032a339632812ae7b9984 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 25 Feb 2015 18:22:41 +0800 Subject: [PATCH 52/59] Update NEWs --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 7d25d4fa739..99d2953d0a7 100644 --- a/NEWS +++ b/NEWS @@ -35,6 +35,8 @@ parameters). (Laruence) - SPL: + . Fixed bug #69108 ("Segmentation fault" when (de)serializing + SplObjectStorage). (Laruence) . Fixed bug #68557 (RecursiveDirectoryIterator::seek(0) broken after calling getChildren()). (Julien) From d508ff9640469bf451b975d83fd2879710db0b46 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 25 Feb 2015 20:07:02 +0800 Subject: [PATCH 53/59] Improve fix for #69038 --- ext/opcache/Optimizer/zend_optimizer.c | 15 ++++++++++----- ext/opcache/tests/bug69038.phpt | 10 ++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 7829ee7c95b..6da3370ffe8 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -290,15 +290,24 @@ static void replace_tmp_by_const(zend_op_array *op_array, * and allows its reuse. The number of ZEND_CASE instructions * usually terminated by ZEND_FREE that finally kills the value. */ - if (opline->opcode == ZEND_CASE) { + if (opline->opcode == ZEND_CASE || opline->opcode == ZEND_FREE) { zend_op *m, *n; int brk = op_array->last_brk_cont; + zend_bool in_case = 0; while (brk--) { if (op_array->brk_cont_array[brk].start <= (opline - op_array->opcodes) && op_array->brk_cont_array[brk].brk > (opline - op_array->opcodes)) { + in_case = 1; break; } } + + if (!in_case) { + MAKE_NOP(opline); + zval_dtor(val); + break; + } + m = opline; n = op_array->opcodes + op_array->brk_cont_array[brk].brk + 1; while (m < n) { @@ -320,10 +329,6 @@ static void replace_tmp_by_const(zend_op_array *op_array, } zval_dtor(val); break; - } else if (opline->opcode == ZEND_FREE) { - MAKE_NOP(opline); - zval_dtor(val); - break; } else { update_op1_const(op_array, opline, val TSRMLS_CC); break; diff --git a/ext/opcache/tests/bug69038.phpt b/ext/opcache/tests/bug69038.phpt index 9aeecfeeceb..bba3c33cb66 100644 --- a/ext/opcache/tests/bug69038.phpt +++ b/ext/opcache/tests/bug69038.phpt @@ -39,7 +39,17 @@ function b($b = "bad") { return $b; } var_dump(b()); + +function c() { + switch (PHP_OS) { + default: return "bad"; + case PHP_OS: return "okey"; + } +} + +var_dump(c()); ?> --EXPECT-- string(4) "okey" string(4) "okey" +string(4) "okey" From 34d397e267856a3dc0f6efc39c05fe0bd06529aa Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Wed, 25 Feb 2015 20:49:07 +0800 Subject: [PATCH 54/59] better name --- ext/opcache/Optimizer/zend_optimizer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c index 6da3370ffe8..ca5d41d8d50 100644 --- a/ext/opcache/Optimizer/zend_optimizer.c +++ b/ext/opcache/Optimizer/zend_optimizer.c @@ -293,16 +293,16 @@ static void replace_tmp_by_const(zend_op_array *op_array, if (opline->opcode == ZEND_CASE || opline->opcode == ZEND_FREE) { zend_op *m, *n; int brk = op_array->last_brk_cont; - zend_bool in_case = 0; + zend_bool in_switch = 0; while (brk--) { if (op_array->brk_cont_array[brk].start <= (opline - op_array->opcodes) && op_array->brk_cont_array[brk].brk > (opline - op_array->opcodes)) { - in_case = 1; + in_switch = 1; break; } } - if (!in_case) { + if (!in_switch) { MAKE_NOP(opline); zval_dtor(val); break; From bb491c2de11de37e31888c0368cc2cb38c56f3a6 Mon Sep 17 00:00:00 2001 From: George Wang Date: Wed, 25 Feb 2015 10:48:19 -0500 Subject: [PATCH 55/59] Fixed a bug that header value is not terminated by '\0' when accessed through getenv(). Conflicts: sapi/litespeed/lsapilib.c --- sapi/litespeed/lsapilib.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/sapi/litespeed/lsapilib.c b/sapi/litespeed/lsapilib.c index fdb9ae47ea7..89ef6df3fa2 100644 --- a/sapi/litespeed/lsapilib.c +++ b/sapi/litespeed/lsapilib.c @@ -1390,10 +1390,12 @@ char * LSAPI_GetHeader_r( LSAPI_Request * pReq, int headerIndex ) off = pReq->m_pHeaderIndex->m_headerOff[ headerIndex ]; if ( !off ) return NULL; - if ( *(pReq->m_pHttpHeader + off + - pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) ) - *( pReq->m_pHttpHeader + off + - pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) = 0; + if ( *(pReq->m_pHttpHeader + off + + pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) ) + { + *( pReq->m_pHttpHeader + off + + pReq->m_pHeaderIndex->m_headerLen[ headerIndex ]) = 0; + } return pReq->m_pHttpHeader + off; } @@ -1830,12 +1832,21 @@ ssize_t LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, size_t le static char * GetHeaderVar( LSAPI_Request * pReq, const char * name ) { int i; + char * pValue; for( i = 0; i < H_TRANSFER_ENCODING; ++i ) { if ( pReq->m_pHeaderIndex->m_headerOff[i] ) { if ( strcmp( name, CGI_HEADERS[i] ) == 0 ) - return pReq->m_pHttpHeader + pReq->m_pHeaderIndex->m_headerOff[i]; + { + pValue = pReq->m_pHttpHeader + + pReq->m_pHeaderIndex->m_headerOff[i]; + if ( *(pValue + pReq->m_pHeaderIndex->m_headerLen[i]) != '\0') + { + *(pValue + pReq->m_pHeaderIndex->m_headerLen[i]) = '\0'; + } + return pValue; + } } } if ( pReq->m_pHeader->m_cntUnknownHeaders > 0 ) @@ -1862,7 +1873,15 @@ static char * GetHeaderVar( LSAPI_Request * pReq, const char * name ) ++p; ++pKey; } if (( pKey == pKeyEnd )&& (!*p )) - return pReq->m_pHttpHeader + pCur->valueOff; + { + pValue = pReq->m_pHttpHeader + pCur->valueOff; + + if ( *(pValue + pCur->valueLen) != '\0') + { + *(pValue + pCur->valueLen) = '\0'; + } + return pValue; + } ++pCur; } } From ff86267632b650ee900831b7220825eb58e16a29 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 25 Feb 2015 23:20:47 +0300 Subject: [PATCH 56/59] Fixed compilation warnings --- Zend/zend_execute.c | 21 +++--- Zend/zend_vm_def.h | 13 ++-- Zend/zend_vm_execute.h | 144 ++++++++++++++++++++++++----------------- Zend/zend_vm_gen.php | 4 +- 4 files changed, 105 insertions(+), 77 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 0cf2f2c53eb..6d679f05631 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -511,22 +511,19 @@ static inline void zend_assign_to_variable_reference(zval *variable_ptr, zval *v } /* this should modify object only if it's empty */ -static inline int make_real_object(zval **object_ptr) +static inline int make_real_object(zval *object) { - zval *object = *object_ptr; - - ZVAL_DEREF(object); if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE) - || (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0)) { + if (EXPECTED(Z_TYPE_P(object) <= IS_FALSE)) { + /* nothing to destroy */ + } else if (EXPECTED((Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) { zval_ptr_dtor_nogc(object); - object_init(object); - zend_error(E_WARNING, "Creating default object from empty value"); } else { return 0; } + object_init(object); + zend_error(E_WARNING, "Creating default object from empty value"); } - *object_ptr = object; return 1; } @@ -933,7 +930,7 @@ static zend_always_inline void zend_assign_to_object(zval *retval, zval *object, zend_object *zobj = Z_OBJ_P(object); zval *property; - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { property = OBJ_PROP(zobj, prop_offset); if (Z_TYPE_P(property) != IS_UNDEF) { fast_assign: @@ -1578,7 +1575,7 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c zend_object *zobj = Z_OBJ_P(container); zval *retval; - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_INDIRECT(result, retval); @@ -2022,7 +2019,7 @@ static zend_execute_data *zend_vm_stack_copy_call_frame(zend_execute_data *call, static zend_always_inline void zend_vm_stack_extend_call_frame(zend_execute_data **call, uint32_t passed_args, uint32_t additional_args) /* {{{ */ { - if (EXPECTED(EG(vm_stack_end) - EG(vm_stack_top) > additional_args)) { + if (EXPECTED((uint32_t)(EG(vm_stack_end) - EG(vm_stack_top)) > additional_args)) { EG(vm_stack_top) += additional_args; } else { *call = zend_vm_stack_copy_call_frame(*call, passed_args, additional_args); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 04b1d1d6962..52590853ee2 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -366,7 +366,8 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR| value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to assign property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -765,7 +766,8 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C do { if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(retval); @@ -854,7 +856,8 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR| do { if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); break; @@ -1440,7 +1443,7 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMPVAR|CV) EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -1555,7 +1558,7 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR|CV) EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index d4e29353fc1..b9bcbf17000 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -307,6 +307,7 @@ static zend_uchar zend_user_opcodes[256] = {0, }; static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op); +static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS); #undef OPLINE @@ -323,12 +324,12 @@ static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, const zend #undef HANDLE_EXCEPTION #undef HANDLE_EXCEPTION_LEAVE #define CHECK_EXCEPTION() LOAD_OPLINE() -#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE() +#define HANDLE_EXCEPTION() LOAD_OPLINE(); return ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(execute_data) #define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE() -#define ZEND_VM_CONTINUE() return 0 +#define ZEND_VM_CONTINUE() return EX(opline)->handler(execute_data) #define ZEND_VM_RETURN() return -1 -#define ZEND_VM_ENTER() return 1 -#define ZEND_VM_LEAVE() return 2 +#define ZEND_VM_ENTER() return EG(current_execute_data)->opline->handler(EG(current_execute_data)); +#define ZEND_VM_LEAVE() return EG(current_execute_data)->opline->handler(EG(current_execute_data)); #define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data @@ -4269,7 +4270,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_ EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -4334,7 +4335,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -7211,7 +7212,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAN EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -7276,7 +7277,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HA EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -8363,7 +8364,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -8429,7 +8430,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCOD EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -9770,7 +9771,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HA EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -10850,7 +10851,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDL EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -11273,7 +11274,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_TMPVAR_HANDLER(ZEND_OPCODE_H EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -12951,7 +12952,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to assign property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -13348,7 +13350,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(retval); @@ -13436,7 +13439,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_ do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); break; @@ -13630,7 +13634,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -15832,7 +15836,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to assign property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -16229,7 +16234,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(retval); @@ -16317,7 +16323,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); break; @@ -16511,7 +16518,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -17350,7 +17357,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMPVAR(int (* value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to assign property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -17749,7 +17757,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMPVAR(incdec_ do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(retval); @@ -17838,7 +17847,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMPVAR(incdec do { if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); break; @@ -18033,7 +18043,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_H EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -18753,7 +18763,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to assign property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -19115,7 +19126,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(retval); @@ -19203,7 +19215,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); break; @@ -19296,7 +19309,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -19410,7 +19423,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -20961,7 +20974,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to assign property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -21323,7 +21337,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(retval); @@ -21411,7 +21426,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_ do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); break; @@ -21504,7 +21520,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -21618,7 +21634,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -22349,7 +22365,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMPVAR(int value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to assign property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -22712,7 +22729,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMPVAR(incd do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(retval); @@ -22801,7 +22819,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMPVAR(inc do { if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); break; @@ -22895,7 +22914,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCOD EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -23010,7 +23029,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCO EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -25412,7 +25431,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to assign property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -25809,7 +25829,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(retval); @@ -25897,7 +25918,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); break; @@ -26294,7 +26316,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -26408,7 +26430,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -29801,7 +29823,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to assign property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -30198,7 +30221,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(retval); @@ -30286,7 +30310,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); break; @@ -30510,7 +30535,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -30624,7 +30649,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -31853,7 +31878,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMPVAR(int (*b value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to assign property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -32252,7 +32278,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMPVAR(incdec_t do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(retval); @@ -32341,7 +32368,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMPVAR(incdec_ do { if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { - if (UNEXPECTED(!make_real_object(&object))) { + ZVAL_DEREF(object); + if (UNEXPECTED(!make_real_object(object))) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); break; @@ -32566,7 +32594,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HA EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -32681,7 +32709,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_H EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -34469,7 +34497,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCOD EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -36124,7 +36152,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_H EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); @@ -36786,7 +36814,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCO EXPECTED(zobj->ce == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { uint32_t prop_offset = (uint32_t)(intptr_t)CACHED_PTR(Z_CACHE_SLOT_P(offset) + sizeof(void*)); - if (EXPECTED(prop_offset != ZEND_DYNAMIC_PROPERTY_OFFSET)) { + if (EXPECTED(prop_offset != (uint32_t)ZEND_DYNAMIC_PROPERTY_OFFSET)) { retval = OBJ_PROP(zobj, prop_offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { ZVAL_COPY(EX_VAR(opline->result.var), retval); diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index 7d435fa4cb0..cad9e8b75b7 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -967,7 +967,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name, out($f,"#undef LOAD_OPLINE\n"); out($f,"#undef SAVE_OPLINE\n"); out($f,"#define OPLINE opline\n"); - out($f,"#define DCL_OPLINE zend_op *opline;\n"); + out($f,"#define DCL_OPLINE const zend_op *opline;\n"); out($f,"#define USE_OPLINE\n"); out($f,"#define LOAD_OPLINE() opline = EX(opline)\n"); out($f,"#define SAVE_OPLINE() EX(opline) = opline\n"); @@ -993,7 +993,7 @@ function gen_executor($f, $skl, $spec, $kind, $executor_name, $initializer_name, out($f,"#undef LOAD_OPLINE\n"); out($f,"#undef SAVE_OPLINE\n"); out($f,"#define OPLINE opline\n"); - out($f,"#define DCL_OPLINE zend_op *opline;\n"); + out($f,"#define DCL_OPLINE const zend_op *opline;\n"); out($f,"#define USE_OPLINE\n"); out($f,"#define LOAD_OPLINE() opline = EX(opline)\n"); out($f,"#define SAVE_OPLINE() EX(opline) = opline\n"); From 803e1432c819a1c8fda2594d1d3f7ba3fa265d19 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 25 Feb 2015 23:23:10 +0300 Subject: [PATCH 57/59] Revert a part committted by mistake --- Zend/zend_vm_execute.h | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index b9bcbf17000..24f1ca0850d 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -307,7 +307,6 @@ static zend_uchar zend_user_opcodes[256] = {0, }; static opcode_handler_t zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op); -static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS); #undef OPLINE @@ -324,12 +323,12 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER #undef HANDLE_EXCEPTION #undef HANDLE_EXCEPTION_LEAVE #define CHECK_EXCEPTION() LOAD_OPLINE() -#define HANDLE_EXCEPTION() LOAD_OPLINE(); return ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(execute_data) +#define HANDLE_EXCEPTION() LOAD_OPLINE(); ZEND_VM_CONTINUE() #define HANDLE_EXCEPTION_LEAVE() LOAD_OPLINE(); ZEND_VM_LEAVE() -#define ZEND_VM_CONTINUE() return EX(opline)->handler(execute_data) +#define ZEND_VM_CONTINUE() return 0 #define ZEND_VM_RETURN() return -1 -#define ZEND_VM_ENTER() return EG(current_execute_data)->opline->handler(EG(current_execute_data)); -#define ZEND_VM_LEAVE() return EG(current_execute_data)->opline->handler(EG(current_execute_data)); +#define ZEND_VM_ENTER() return 1 +#define ZEND_VM_LEAVE() return 2 #define ZEND_VM_DISPATCH(opcode, opline) return zend_vm_get_opcode_handler(opcode, opline)(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); #define ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_INTERNAL execute_data From 716da71446ebbd40fa6cf2cea8a4b70f504cc3cd Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 26 Feb 2015 01:28:47 +0300 Subject: [PATCH 58/59] Don't inline slow path --- Zend/zend_operators.c | 32 ++++++++++++++++++++++++++++++++ Zend/zend_operators.h | 32 +++----------------------------- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 0a084036b8c..d8be615c162 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -2870,6 +2870,38 @@ ZEND_API const char* zend_memnrstr_ex(const char *haystack, const char *needle, } /* }}} */ +#if !ZEND_DVAL_TO_LVAL_CAST_OK +# if SIZEOF_ZEND_LONG == 4 +ZEND_API zend_long zend_dval_to_lval_slow(double d) +{ + double two_pow_32 = pow(2., 32.), + dmod; + + dmod = fmod(d, two_pow_32); + if (dmod < 0) { + /* we're going to make this number positive; call ceil() + * to simulate rounding towards 0 of the negative number */ + dmod = ceil(dmod);// + two_pow_32; + } + return (zend_long)(zend_ulong)dmod; +} +#else +ZEND_API zend_long zend_dval_to_lval_slow(double d) +{ + double two_pow_64 = pow(2., 64.), + dmod; + + dmod = fmod(d, two_pow_64); + if (dmod < 0) { + /* no need to call ceil; original double must have had no + * fractional part, hence dmod does not have one either */ + dmod += two_pow_64; + } + return (zend_long)(zend_ulong)dmod; +} +#endif +#endif + /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index d66f82d3645..31d84fc5b1f 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -108,41 +108,15 @@ static zend_always_inline zend_long zend_dval_to_lval(double d) return 0; } } -#elif SIZEOF_ZEND_LONG == 4 -static zend_always_inline zend_long zend_dval_to_lval(double d) -{ - if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) { - return 0; - } else if (!ZEND_DOUBLE_FITS_LONG(d)) { - double two_pow_32 = pow(2., 32.), - dmod; - - dmod = fmod(d, two_pow_32); - if (dmod < 0) { - /* we're going to make this number positive; call ceil() - * to simulate rounding towards 0 of the negative number */ - dmod = ceil(dmod) + two_pow_32; - } - return (zend_long)(zend_ulong)dmod; - } - return (zend_long)d; -} #else +ZEND_API zend_long zend_dval_to_lval_slow(double d); + static zend_always_inline zend_long zend_dval_to_lval(double d) { if (UNEXPECTED(!zend_finite(d)) || UNEXPECTED(zend_isnan(d))) { return 0; } else if (!ZEND_DOUBLE_FITS_LONG(d)) { - double two_pow_64 = pow(2., 64.), - dmod; - - dmod = fmod(d, two_pow_64); - if (dmod < 0) { - /* no need to call ceil; original double must have had no - * fractional part, hence dmod does not have one either */ - dmod += two_pow_64; - } - return (zend_long)(zend_ulong)dmod; + return zend_dval_to_lval_slow(d); } return (zend_long)d; } From ace1f82e9c49ddbefbc0da97d2abf33cb785298b Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 26 Feb 2015 02:49:19 +0300 Subject: [PATCH 59/59] Improved ASSIGN_DIM handler --- Zend/zend_vm_def.h | 59 ++++-- Zend/zend_vm_execute.h | 448 ++++++++++++++++++++++++++++++----------- 2 files changed, 375 insertions(+), 132 deletions(-) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 52590853ee2..33760decf58 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1714,7 +1714,6 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMPVAR|UNUSED|CV) zend_free_op free_op1; zval *object_ptr; zend_free_op free_op2, free_op_data1; - zval rv; zval *value; zval *variable_ptr; zval *dim; @@ -1729,12 +1728,20 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMPVAR|UNUSED|CV) ZEND_VM_C_LABEL(try_assign_dim): if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { ZEND_VM_C_LABEL(try_assign_dim_array): - dim = GET_OP2_ZVAL_PTR(BP_VAR_R); - zend_fetch_dimension_address_W(&rv, object_ptr, dim, OP2_TYPE); - FREE_OP2(); + if (OP2_TYPE == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); + if (UNEXPECTED(variable_ptr == NULL)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + variable_ptr = &EG(error_zval); + } + } else { + dim = GET_OP2_ZVAL_PTR(BP_VAR_R); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, OP2_TYPE, BP_VAR_W); + FREE_OP2(); + } value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - variable_ptr = Z_INDIRECT(rv); if (UNEXPECTED(variable_ptr == &EG(error_zval))) { FREE_OP(free_op_data1); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -1755,21 +1762,41 @@ ZEND_VM_C_LABEL(try_assign_dim_array): zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); FREE_OP2(); - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && - EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { - zend_long offset; + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + zend_long offset; - dim = GET_OP2_ZVAL_PTR(BP_VAR_R); - offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); - FREE_OP2(); - value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + dim = GET_OP2_ZVAL_PTR(BP_VAR_R); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + FREE_OP2(); + value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + FREE_OP(free_op_data1); + } else { + zval_ptr_dtor_nogc(object_ptr); +ZEND_VM_C_LABEL(assign_dim_convert_to_array): + ZVAL_NEW_ARR(object_ptr); + zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + ZEND_VM_C_GOTO(try_assign_dim_array); + } } else if (EXPECTED(Z_ISREF_P(object_ptr))) { object_ptr = Z_REFVAL_P(object_ptr); ZEND_VM_C_GOTO(try_assign_dim); + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (UNEXPECTED(object_ptr == &EG(error_zval))) { + ZEND_VM_C_GOTO(assign_dim_clean); + } + ZEND_VM_C_GOTO(assign_dim_convert_to_array); } else { - ZEND_VM_C_GOTO(try_assign_dim_array); + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +ZEND_VM_C_LABEL(assign_dim_clean): + dim = GET_OP2_ZVAL_PTR(BP_VAR_R); + FREE_OP2(); + value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + FREE_OP(free_op_data1); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } FREE_OP1_VAR_PTR(); /* assign_dim has two opcodes! */ diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 24f1ca0850d..5832af633a7 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -13800,7 +13800,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN zend_free_op free_op1; zval *object_ptr; zend_free_op free_op_data1; - zval rv; zval *value; zval *variable_ptr; zval *dim; @@ -13815,12 +13814,20 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN try_assign_dim: if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: - dim = EX_CONSTANT(opline->op2); - zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CONST); + if (IS_CONST == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); + if (UNEXPECTED(variable_ptr == NULL)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + variable_ptr = &EG(error_zval); + } + } else { + dim = EX_CONSTANT(opline->op2); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CONST, BP_VAR_W); + } value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - variable_ptr = Z_INDIRECT(rv); if (UNEXPECTED(variable_ptr == &EG(error_zval))) { FREE_OP(free_op_data1); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -13841,21 +13848,41 @@ try_assign_dim_array: zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && - EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { - zend_long offset; + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + zend_long offset; - dim = EX_CONSTANT(opline->op2); - offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + dim = EX_CONSTANT(opline->op2); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); - value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + FREE_OP(free_op_data1); + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + ZVAL_NEW_ARR(object_ptr); + zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + goto try_assign_dim_array; + } } else if (EXPECTED(Z_ISREF_P(object_ptr))) { object_ptr = Z_REFVAL_P(object_ptr); goto try_assign_dim; + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (UNEXPECTED(object_ptr == &EG(error_zval))) { + goto assign_dim_clean; + } + goto assign_dim_convert_to_array; } else { - goto try_assign_dim_array; + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + dim = EX_CONSTANT(opline->op2); + + value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + FREE_OP(free_op_data1); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_dim has two opcodes! */ @@ -15311,7 +15338,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA zend_free_op free_op1; zval *object_ptr; zend_free_op free_op_data1; - zval rv; zval *value; zval *variable_ptr; zval *dim; @@ -15326,12 +15352,20 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA try_assign_dim: if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: - dim = NULL; - zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_UNUSED); + if (IS_UNUSED == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); + if (UNEXPECTED(variable_ptr == NULL)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + variable_ptr = &EG(error_zval); + } + } else { + dim = NULL; + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_UNUSED, BP_VAR_W); + } value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - variable_ptr = Z_INDIRECT(rv); if (UNEXPECTED(variable_ptr == &EG(error_zval))) { FREE_OP(free_op_data1); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -15352,21 +15386,41 @@ try_assign_dim_array: zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && - EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { - zend_long offset; + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + zend_long offset; - dim = NULL; - offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + dim = NULL; + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); - value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + FREE_OP(free_op_data1); + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + ZVAL_NEW_ARR(object_ptr); + zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + goto try_assign_dim_array; + } } else if (EXPECTED(Z_ISREF_P(object_ptr))) { object_ptr = Z_REFVAL_P(object_ptr); goto try_assign_dim; + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (UNEXPECTED(object_ptr == &EG(error_zval))) { + goto assign_dim_clean; + } + goto assign_dim_convert_to_array; } else { - goto try_assign_dim_array; + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + dim = NULL; + + value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + FREE_OP(free_op_data1); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_dim has two opcodes! */ @@ -16684,7 +16738,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE zend_free_op free_op1; zval *object_ptr; zend_free_op free_op_data1; - zval rv; zval *value; zval *variable_ptr; zval *dim; @@ -16699,12 +16752,20 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE try_assign_dim: if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: - dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CV); + if (IS_CV == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); + if (UNEXPECTED(variable_ptr == NULL)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + variable_ptr = &EG(error_zval); + } + } else { + dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CV, BP_VAR_W); + } value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - variable_ptr = Z_INDIRECT(rv); if (UNEXPECTED(variable_ptr == &EG(error_zval))) { FREE_OP(free_op_data1); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -16725,21 +16786,41 @@ try_assign_dim_array: zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && - EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { - zend_long offset; + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + zend_long offset; - dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); - value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + FREE_OP(free_op_data1); + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + ZVAL_NEW_ARR(object_ptr); + zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + goto try_assign_dim_array; + } } else if (EXPECTED(Z_ISREF_P(object_ptr))) { object_ptr = Z_REFVAL_P(object_ptr); goto try_assign_dim; + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (UNEXPECTED(object_ptr == &EG(error_zval))) { + goto assign_dim_clean; + } + goto assign_dim_convert_to_array; } else { - goto try_assign_dim_array; + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + + value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + FREE_OP(free_op_data1); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_dim has two opcodes! */ @@ -18210,7 +18291,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HA zend_free_op free_op1; zval *object_ptr; zend_free_op free_op2, free_op_data1; - zval rv; zval *value; zval *variable_ptr; zval *dim; @@ -18225,12 +18305,20 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HA try_assign_dim: if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: - dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - zend_fetch_dimension_address_W(&rv, object_ptr, dim, (IS_TMP_VAR|IS_VAR)); - zval_ptr_dtor_nogc(free_op2); + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); + if (UNEXPECTED(variable_ptr == NULL)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + variable_ptr = &EG(error_zval); + } + } else { + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); + } value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - variable_ptr = Z_INDIRECT(rv); if (UNEXPECTED(variable_ptr == &EG(error_zval))) { FREE_OP(free_op_data1); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -18251,21 +18339,41 @@ try_assign_dim_array: zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); zval_ptr_dtor_nogc(free_op2); - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && - EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { - zend_long offset; + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + zend_long offset; - dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); - zval_ptr_dtor_nogc(free_op2); - value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); + value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + FREE_OP(free_op_data1); + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + ZVAL_NEW_ARR(object_ptr); + zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + goto try_assign_dim_array; + } } else if (EXPECTED(Z_ISREF_P(object_ptr))) { object_ptr = Z_REFVAL_P(object_ptr); goto try_assign_dim; + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (UNEXPECTED(object_ptr == &EG(error_zval))) { + goto assign_dim_clean; + } + goto assign_dim_convert_to_array; } else { - goto try_assign_dim_array; + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + zval_ptr_dtor_nogc(free_op2); + value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + FREE_OP(free_op_data1); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_dim has two opcodes! */ @@ -26584,7 +26692,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND zval *object_ptr; zend_free_op free_op_data1; - zval rv; zval *value; zval *variable_ptr; zval *dim; @@ -26599,12 +26706,20 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND try_assign_dim: if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: - dim = EX_CONSTANT(opline->op2); - zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CONST); + if (IS_CONST == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); + if (UNEXPECTED(variable_ptr == NULL)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + variable_ptr = &EG(error_zval); + } + } else { + dim = EX_CONSTANT(opline->op2); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CONST, BP_VAR_W); + } value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - variable_ptr = Z_INDIRECT(rv); if (UNEXPECTED(variable_ptr == &EG(error_zval))) { FREE_OP(free_op_data1); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -26625,21 +26740,41 @@ try_assign_dim_array: zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && - EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { - zend_long offset; + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + zend_long offset; - dim = EX_CONSTANT(opline->op2); - offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + dim = EX_CONSTANT(opline->op2); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); - value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + FREE_OP(free_op_data1); + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + ZVAL_NEW_ARR(object_ptr); + zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + goto try_assign_dim_array; + } } else if (EXPECTED(Z_ISREF_P(object_ptr))) { object_ptr = Z_REFVAL_P(object_ptr); goto try_assign_dim; + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (UNEXPECTED(object_ptr == &EG(error_zval))) { + goto assign_dim_clean; + } + goto assign_dim_convert_to_array; } else { - goto try_assign_dim_array; + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + dim = EX_CONSTANT(opline->op2); + + value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + FREE_OP(free_op_data1); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } /* assign_dim has two opcodes! */ @@ -29008,7 +29143,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN zval *object_ptr; zend_free_op free_op_data1; - zval rv; zval *value; zval *variable_ptr; zval *dim; @@ -29023,12 +29157,20 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAN try_assign_dim: if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: - dim = NULL; - zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_UNUSED); + if (IS_UNUSED == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); + if (UNEXPECTED(variable_ptr == NULL)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + variable_ptr = &EG(error_zval); + } + } else { + dim = NULL; + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_UNUSED, BP_VAR_W); + } value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - variable_ptr = Z_INDIRECT(rv); if (UNEXPECTED(variable_ptr == &EG(error_zval))) { FREE_OP(free_op_data1); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -29049,21 +29191,41 @@ try_assign_dim_array: zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && - EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { - zend_long offset; + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + zend_long offset; - dim = NULL; - offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + dim = NULL; + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); - value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + FREE_OP(free_op_data1); + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + ZVAL_NEW_ARR(object_ptr); + zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + goto try_assign_dim_array; + } } else if (EXPECTED(Z_ISREF_P(object_ptr))) { object_ptr = Z_REFVAL_P(object_ptr); goto try_assign_dim; + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (UNEXPECTED(object_ptr == &EG(error_zval))) { + goto assign_dim_clean; + } + goto assign_dim_convert_to_array; } else { - goto try_assign_dim_array; + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + dim = NULL; + + value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + FREE_OP(free_op_data1); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } /* assign_dim has two opcodes! */ @@ -30766,7 +30928,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER zval *object_ptr; zend_free_op free_op_data1; - zval rv; zval *value; zval *variable_ptr; zval *dim; @@ -30781,12 +30942,20 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER try_assign_dim: if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: - dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_CV); + if (IS_CV == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); + if (UNEXPECTED(variable_ptr == NULL)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + variable_ptr = &EG(error_zval); + } + } else { + dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, IS_CV, BP_VAR_W); + } value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - variable_ptr = Z_INDIRECT(rv); if (UNEXPECTED(variable_ptr == &EG(error_zval))) { FREE_OP(free_op_data1); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -30807,21 +30976,41 @@ try_assign_dim_array: zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && - EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { - zend_long offset; + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + zend_long offset; - dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); - offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); - value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + FREE_OP(free_op_data1); + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + ZVAL_NEW_ARR(object_ptr); + zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + goto try_assign_dim_array; + } } else if (EXPECTED(Z_ISREF_P(object_ptr))) { object_ptr = Z_REFVAL_P(object_ptr); goto try_assign_dim; + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (UNEXPECTED(object_ptr == &EG(error_zval))) { + goto assign_dim_clean; + } + goto assign_dim_convert_to_array; } else { - goto try_assign_dim_array; + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + dim = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var); + + value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + FREE_OP(free_op_data1); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } /* assign_dim has two opcodes! */ @@ -32827,7 +33016,6 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HAN zval *object_ptr; zend_free_op free_op2, free_op_data1; - zval rv; zval *value; zval *variable_ptr; zval *dim; @@ -32842,12 +33030,20 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HAN try_assign_dim: if (EXPECTED(Z_TYPE_P(object_ptr) == IS_ARRAY)) { try_assign_dim_array: - dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - zend_fetch_dimension_address_W(&rv, object_ptr, dim, (IS_TMP_VAR|IS_VAR)); - zval_ptr_dtor_nogc(free_op2); + if ((IS_TMP_VAR|IS_VAR) == IS_UNUSED) { + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_hash_next_index_insert(Z_ARRVAL_P(object_ptr), &EG(uninitialized_zval)); + if (UNEXPECTED(variable_ptr == NULL)) { + zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied"); + variable_ptr = &EG(error_zval); + } + } else { + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + SEPARATE_ARRAY(object_ptr); + variable_ptr = zend_fetch_dimension_address_inner(Z_ARRVAL_P(object_ptr), dim, (IS_TMP_VAR|IS_VAR), BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); + } value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); - variable_ptr = Z_INDIRECT(rv); if (UNEXPECTED(variable_ptr == &EG(error_zval))) { FREE_OP(free_op_data1); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -32868,21 +33064,41 @@ try_assign_dim_array: zend_assign_to_object_dim(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object_ptr, property_name, (opline+1)->op1_type, (opline+1)->op1, execute_data); zval_ptr_dtor_nogc(free_op2); - } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && - EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { - zend_long offset; + } else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) { + if (EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { + zend_long offset; - dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); - zval_ptr_dtor_nogc(free_op2); - value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); - zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); - FREE_OP(free_op_data1); + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W); + zval_ptr_dtor_nogc(free_op2); + value = get_zval_ptr_deref((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + zend_assign_to_string_offset(object_ptr, offset, value, (UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL)); + FREE_OP(free_op_data1); + } else { + zval_ptr_dtor_nogc(object_ptr); +assign_dim_convert_to_array: + ZVAL_NEW_ARR(object_ptr); + zend_hash_init(Z_ARRVAL_P(object_ptr), 8, NULL, ZVAL_PTR_DTOR, 0); + goto try_assign_dim_array; + } } else if (EXPECTED(Z_ISREF_P(object_ptr))) { object_ptr = Z_REFVAL_P(object_ptr); goto try_assign_dim; + } else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) { + if (UNEXPECTED(object_ptr == &EG(error_zval))) { + goto assign_dim_clean; + } + goto assign_dim_convert_to_array; } else { - goto try_assign_dim_array; + zend_error(E_WARNING, "Cannot use a scalar value as an array"); +assign_dim_clean: + dim = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + zval_ptr_dtor_nogc(free_op2); + value = get_zval_ptr((opline+1)->op1_type, (opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); + FREE_OP(free_op_data1); + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_NULL(EX_VAR(opline->result.var)); + } } /* assign_dim has two opcodes! */