From 2361745806553db9099542d9237ade00dcee799b Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 31 Oct 2013 08:57:12 +0100 Subject: Working commit for constant scalar expressions (with constants). Tests will follow. --- Zend/zend_execute_API.c | 334 +++++++++++++++++++++++++----------------------- 1 file changed, 177 insertions(+), 157 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 779e6d886f..eabebacce4 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -478,188 +478,208 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco if (IS_CONSTANT_VISITED(p)) { zend_error(E_ERROR, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p)); - } else if ((Z_TYPE_P(p) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { - int refcount; - zend_uchar is_ref; + return FAILURE; + } + switch (Z_TYPE_P(p) & IS_CONSTANT_TYPE_MASK) { + case IS_CONSTANT: { + int refcount; + zend_uchar is_ref; - SEPARATE_ZVAL_IF_NOT_REF(pp); - p = *pp; + SEPARATE_ZVAL_IF_NOT_REF(pp); + p = *pp; - MARK_CONSTANT_VISITED(p); + MARK_CONSTANT_VISITED(p); - refcount = Z_REFCOUNT_P(p); - is_ref = Z_ISREF_P(p); + refcount = Z_REFCOUNT_P(p); + is_ref = Z_ISREF_P(p); - if (!zend_get_constant_ex(p->value.str.val, p->value.str.len, &const_value, scope, Z_REAL_TYPE_P(p) TSRMLS_CC)) { - char *actual = Z_STRVAL_P(p); + if (!zend_get_constant_ex(p->value.str.val, p->value.str.len, &const_value, scope, Z_REAL_TYPE_P(p) TSRMLS_CC)) { + char *actual = Z_STRVAL_P(p); - if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) { - zend_error(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(p)); - Z_STRLEN_P(p) -= ((colon - Z_STRVAL_P(p)) + 1); - if (inline_change) { - colon = estrndup(colon, Z_STRLEN_P(p)); - str_efree(Z_STRVAL_P(p)); - Z_STRVAL_P(p) = colon; - } else { - Z_STRVAL_P(p) = colon + 1; - } - } else { - char *save = actual, *slash; - int actual_len = Z_STRLEN_P(p); - if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) && (slash = (char *)zend_memrchr(actual, '\\', actual_len))) { - actual = slash + 1; - actual_len -= (actual - Z_STRVAL_P(p)); + if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) { + zend_error(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(p)); + Z_STRLEN_P(p) -= ((colon - Z_STRVAL_P(p)) + 1); if (inline_change) { - actual = estrndup(actual, actual_len); - Z_STRVAL_P(p) = actual; - Z_STRLEN_P(p) = actual_len; - } - } - if (actual[0] == '\\') { - if (inline_change) { - memmove(Z_STRVAL_P(p), Z_STRVAL_P(p)+1, Z_STRLEN_P(p)); - --Z_STRLEN_P(p); + colon = estrndup(colon, Z_STRLEN_P(p)); + str_efree(Z_STRVAL_P(p)); + Z_STRVAL_P(p) = colon; } else { - ++actual; + Z_STRVAL_P(p) = colon + 1; } - --actual_len; - } - if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) { - int fix_save = 0; - if (save[0] == '\\') { - save++; - fix_save = 1; + } else { + char *save = actual, *slash; + int actual_len = Z_STRLEN_P(p); + if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) && (slash = (char *)zend_memrchr(actual, '\\', actual_len))) { + actual = slash + 1; + actual_len -= (actual - Z_STRVAL_P(p)); + if (inline_change) { + actual = estrndup(actual, actual_len); + Z_STRVAL_P(p) = actual; + Z_STRLEN_P(p) = actual_len; + } } - zend_error(E_ERROR, "Undefined constant '%s'", save); - if (fix_save) { - save--; + if (actual[0] == '\\') { + if (inline_change) { + memmove(Z_STRVAL_P(p), Z_STRVAL_P(p)+1, Z_STRLEN_P(p)); + --Z_STRLEN_P(p); + } else { + ++actual; + } + --actual_len; } - if (inline_change) { + if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) { + int fix_save = 0; + if (save[0] == '\\') { + save++; + fix_save = 1; + } + zend_error(E_ERROR, "Undefined constant '%s'", save); + if (fix_save) { + save--; + } + if (inline_change) { + str_efree(save); + } + save = NULL; + } + if (inline_change && save && save != actual) { str_efree(save); } - save = NULL; - } - if (inline_change && save && save != actual) { - str_efree(save); + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); + p->type = IS_STRING; + if (!inline_change) { + Z_STRVAL_P(p) = actual; + Z_STRLEN_P(p) = actual_len; + zval_copy_ctor(p); + } } - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); - p->type = IS_STRING; - if (!inline_change) { - Z_STRVAL_P(p) = actual; - Z_STRLEN_P(p) = actual_len; - zval_copy_ctor(p); + } else { + if (inline_change) { + str_efree(Z_STRVAL_P(p)); } + *p = const_value; } - } else { - if (inline_change) { - str_efree(Z_STRVAL_P(p)); - } - *p = const_value; - } - Z_SET_REFCOUNT_P(p, refcount); - Z_SET_ISREF_TO_P(p, is_ref); - } else if (Z_TYPE_P(p) == IS_CONSTANT_ARRAY) { - zval **element, *new_val; - char *str_index; - uint str_index_len; - ulong num_index; - int ret; - - SEPARATE_ZVAL_IF_NOT_REF(pp); - p = *pp; - Z_TYPE_P(p) = IS_ARRAY; - - if (!inline_change) { - zval *tmp; - HashTable *tmp_ht = NULL; - - ALLOC_HASHTABLE(tmp_ht); - zend_hash_init(tmp_ht, zend_hash_num_elements(Z_ARRVAL_P(p)), NULL, ZVAL_PTR_DTOR, 0); - zend_hash_copy(tmp_ht, Z_ARRVAL_P(p), (copy_ctor_func_t) zval_deep_copy, (void *) &tmp, sizeof(zval *)); - Z_ARRVAL_P(p) = tmp_ht; + Z_SET_REFCOUNT_P(p, refcount); + Z_SET_ISREF_TO_P(p, is_ref); } - - /* First go over the array and see if there are any constant indices */ - zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); - while (zend_hash_get_current_data(Z_ARRVAL_P(p), (void **) &element) == SUCCESS) { - if (!(Z_TYPE_PP(element) & IS_CONSTANT_INDEX)) { - zend_hash_move_forward(Z_ARRVAL_P(p)); - continue; + break; + + case IS_CONSTANT_ARRAY: { + zval **element, *new_val; + char *str_index; + uint str_index_len; + ulong num_index; + int ret; + + SEPARATE_ZVAL_IF_NOT_REF(pp); + p = *pp; + Z_TYPE_P(p) = IS_ARRAY; + + if (!inline_change) { + zval *tmp; + HashTable *tmp_ht = NULL; + + ALLOC_HASHTABLE(tmp_ht); + zend_hash_init(tmp_ht, zend_hash_num_elements(Z_ARRVAL_P(p)), NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(tmp_ht, Z_ARRVAL_P(p), (copy_ctor_func_t) zval_deep_copy, (void *) &tmp, sizeof(zval *)); + Z_ARRVAL_P(p) = tmp_ht; } - Z_TYPE_PP(element) &= ~IS_CONSTANT_INDEX; - if (zend_hash_get_current_key_ex(Z_ARRVAL_P(p), &str_index, &str_index_len, &num_index, 0, NULL) != HASH_KEY_IS_STRING) { - zend_hash_move_forward(Z_ARRVAL_P(p)); - continue; - } - if (!zend_get_constant_ex(str_index, str_index_len - 3, &const_value, scope, str_index[str_index_len - 2] TSRMLS_CC)) { - char *actual; - const char *save = str_index; - if ((colon = (char*)zend_memrchr(str_index, ':', str_index_len - 3))) { - zend_error(E_ERROR, "Undefined class constant '%s'", str_index); - str_index_len -= ((colon - str_index) + 1); - str_index = colon; - } else { - if (str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) { - if ((actual = (char *)zend_memrchr(str_index, '\\', str_index_len - 3))) { - actual++; - str_index_len -= (actual - str_index); - str_index = actual; + + /* First go over the array and see if there are any constant indices */ + zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); + while (zend_hash_get_current_data(Z_ARRVAL_P(p), (void **) &element) == SUCCESS) { + if (!(Z_TYPE_PP(element) & IS_CONSTANT_INDEX)) { + zend_hash_move_forward(Z_ARRVAL_P(p)); + continue; + } + Z_TYPE_PP(element) &= ~IS_CONSTANT_INDEX; + if (zend_hash_get_current_key_ex(Z_ARRVAL_P(p), &str_index, &str_index_len, &num_index, 0, NULL) != HASH_KEY_IS_STRING) { + zend_hash_move_forward(Z_ARRVAL_P(p)); + continue; + } + if (str_index[str_index_len - 2] == IS_CONSTANT_AST) { + zend_ast_evaluate(&const_value, *(zend_ast **)str_index); + ZEND_AST_DEL_REF(*(zend_ast **)str_index); + } else if (!zend_get_constant_ex(str_index, str_index_len - 3, &const_value, scope, str_index[str_index_len - 2] TSRMLS_CC)) { + char *actual; + const char *save = str_index; + if ((colon = (char*)zend_memrchr(str_index, ':', str_index_len - 3))) { + zend_error(E_ERROR, "Undefined class constant '%s'", str_index); + str_index_len -= ((colon - str_index) + 1); + str_index = colon; + } else { + if (str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) { + if ((actual = (char *)zend_memrchr(str_index, '\\', str_index_len - 3))) { + actual++; + str_index_len -= (actual - str_index); + str_index = actual; + } } + if (str_index[0] == '\\') { + ++str_index; + --str_index_len; + } + if (save[0] == '\\') { + ++save; + } + if ((str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) == 0) { + zend_error(E_ERROR, "Undefined constant '%s'", save); + } + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str_index, str_index); } - if (str_index[0] == '\\') { - ++str_index; - --str_index_len; - } - if (save[0] == '\\') { - ++save; - } - if ((str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) == 0) { - zend_error(E_ERROR, "Undefined constant '%s'", save); - } - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str_index, str_index); + ZVAL_STRINGL(&const_value, str_index, str_index_len-3, 1); } - ZVAL_STRINGL(&const_value, str_index, str_index_len-3, 1); - } - if (Z_REFCOUNT_PP(element) > 1) { - ALLOC_ZVAL(new_val); - *new_val = **element; - zval_copy_ctor(new_val); - Z_SET_REFCOUNT_P(new_val, 1); - Z_UNSET_ISREF_P(new_val); - - /* preserve this bit for inheritance */ - Z_TYPE_PP(element) |= IS_CONSTANT_INDEX; - zval_ptr_dtor(element); - *element = new_val; - } + if (Z_REFCOUNT_PP(element) > 1) { + ALLOC_ZVAL(new_val); + *new_val = **element; + zval_copy_ctor(new_val); + Z_SET_REFCOUNT_P(new_val, 1); + Z_UNSET_ISREF_P(new_val); + + /* preserve this bit for inheritance */ + Z_TYPE_PP(element) |= IS_CONSTANT_INDEX; + zval_ptr_dtor(element); + *element = new_val; + } - switch (Z_TYPE(const_value)) { - case IS_STRING: - ret = zend_symtable_update_current_key(Z_ARRVAL_P(p), Z_STRVAL(const_value), Z_STRLEN(const_value) + 1, HASH_UPDATE_KEY_IF_BEFORE); - break; - case IS_BOOL: - case IS_LONG: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, Z_LVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL); - break; - case IS_DOUBLE: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, zend_dval_to_lval(Z_DVAL(const_value)), HASH_UPDATE_KEY_IF_BEFORE, NULL); - break; - case IS_NULL: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, "", 1, 0, HASH_UPDATE_KEY_IF_BEFORE, NULL); - break; - default: - ret = SUCCESS; - break; - } - if (ret == SUCCESS) { - zend_hash_move_forward(Z_ARRVAL_P(p)); + switch (Z_TYPE(const_value)) { + case IS_STRING: + ret = zend_symtable_update_current_key(Z_ARRVAL_P(p), Z_STRVAL(const_value), Z_STRLEN(const_value) + 1, HASH_UPDATE_KEY_IF_BEFORE); + break; + case IS_BOOL: + case IS_LONG: + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, Z_LVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL); + break; + case IS_DOUBLE: + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, zend_dval_to_lval(Z_DVAL(const_value)), HASH_UPDATE_KEY_IF_BEFORE, NULL); + break; + case IS_NULL: + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, "", 1, 0, HASH_UPDATE_KEY_IF_BEFORE, NULL); + break; + default: + ret = SUCCESS; + break; + } + if (ret == SUCCESS) { + zend_hash_move_forward(Z_ARRVAL_P(p)); + } + zval_dtor(&const_value); } - zval_dtor(&const_value); + zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC); + zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); + } + break; + + case IS_CONSTANT_AST: { + zend_ast *ast = Z_AST_P(p); + + MARK_CONSTANT_VISITED(p); + + zend_ast_evaluate(p, ast TSRMLS_CC); + ZEND_AST_DEL_REF(ast); } - zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC); - zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); } return 0; } -- cgit v1.2.1 From 466c5dd1fe194ab3d1634695e2dc96240f951f50 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 31 Oct 2013 18:21:37 +0100 Subject: Fixed mem leaks, added tests and ternary operator --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index eabebacce4..a66cdeea92 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -599,7 +599,7 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco continue; } if (str_index[str_index_len - 2] == IS_CONSTANT_AST) { - zend_ast_evaluate(&const_value, *(zend_ast **)str_index); + zend_ast_evaluate(&const_value, *(zend_ast **)str_index TSRMLS_CC); ZEND_AST_DEL_REF(*(zend_ast **)str_index); } else if (!zend_get_constant_ex(str_index, str_index_len - 3, &const_value, scope, str_index[str_index_len - 2] TSRMLS_CC)) { char *actual; -- cgit v1.2.1 From b56c1ca95e16ea1c2a3ce251b91297d0a81a9070 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Thu, 31 Oct 2013 19:05:29 +0100 Subject: Fatal error about self referencing constants fixed --- Zend/zend_execute_API.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index a66cdeea92..e5b68c7de1 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -675,8 +675,6 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco case IS_CONSTANT_AST: { zend_ast *ast = Z_AST_P(p); - MARK_CONSTANT_VISITED(p); - zend_ast_evaluate(p, ast TSRMLS_CC); ZEND_AST_DEL_REF(ast); } -- cgit v1.2.1 From b45043a1b71c29a0c7b8de9e4929dde08bd61216 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 1 Nov 2013 16:16:58 +0100 Subject: converted several switches to ifs and made more opcache friendly --- Zend/zend_execute_API.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index e5b68c7de1..12047f0518 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -520,8 +520,7 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco } if (actual[0] == '\\') { if (inline_change) { - memmove(Z_STRVAL_P(p), Z_STRVAL_P(p)+1, Z_STRLEN_P(p)); - --Z_STRLEN_P(p); + memmove(Z_STRVAL_P(p), Z_STRVAL_P(p)+1, Z_STRLEN_P(p)--); } else { ++actual; } @@ -626,7 +625,7 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco if ((str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) == 0) { zend_error(E_ERROR, "Undefined constant '%s'", save); } - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str_index, str_index); + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str_index, str_index); } ZVAL_STRINGL(&const_value, str_index, str_index_len-3, 1); } @@ -640,7 +639,7 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco /* preserve this bit for inheritance */ Z_TYPE_PP(element) |= IS_CONSTANT_INDEX; - zval_ptr_dtor(element); + zval_ptr_dtor(element); *element = new_val; } -- cgit v1.2.1 From 9647c61dc101b9d460259fedb3731026f0390eeb Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 6 Nov 2013 22:21:07 +0400 Subject: Constant expressions refactoring --- Zend/zend_execute_API.c | 341 ++++++++++++++++++++++++------------------------ 1 file changed, 168 insertions(+), 173 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 12047f0518..769b333d9d 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -478,205 +478,200 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco if (IS_CONSTANT_VISITED(p)) { zend_error(E_ERROR, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p)); - return FAILURE; - } - switch (Z_TYPE_P(p) & IS_CONSTANT_TYPE_MASK) { - case IS_CONSTANT: { - int refcount; - zend_uchar is_ref; + } else if ((Z_TYPE_P(p) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { + int refcount; + zend_uchar is_ref; - SEPARATE_ZVAL_IF_NOT_REF(pp); - p = *pp; + SEPARATE_ZVAL_IF_NOT_REF(pp); + p = *pp; - MARK_CONSTANT_VISITED(p); + MARK_CONSTANT_VISITED(p); - refcount = Z_REFCOUNT_P(p); - is_ref = Z_ISREF_P(p); + refcount = Z_REFCOUNT_P(p); + is_ref = Z_ISREF_P(p); - if (!zend_get_constant_ex(p->value.str.val, p->value.str.len, &const_value, scope, Z_REAL_TYPE_P(p) TSRMLS_CC)) { - char *actual = Z_STRVAL_P(p); + if (!zend_get_constant_ex(p->value.str.val, p->value.str.len, &const_value, scope, Z_REAL_TYPE_P(p) TSRMLS_CC)) { + char *actual = Z_STRVAL_P(p); - if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) { - zend_error(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(p)); - Z_STRLEN_P(p) -= ((colon - Z_STRVAL_P(p)) + 1); + if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) { + zend_error(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(p)); + Z_STRLEN_P(p) -= ((colon - Z_STRVAL_P(p)) + 1); + if (inline_change) { + colon = estrndup(colon, Z_STRLEN_P(p)); + str_efree(Z_STRVAL_P(p)); + Z_STRVAL_P(p) = colon; + } else { + Z_STRVAL_P(p) = colon + 1; + } + } else { + char *save = actual, *slash; + int actual_len = Z_STRLEN_P(p); + if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) && (slash = (char *)zend_memrchr(actual, '\\', actual_len))) { + actual = slash + 1; + actual_len -= (actual - Z_STRVAL_P(p)); if (inline_change) { - colon = estrndup(colon, Z_STRLEN_P(p)); - str_efree(Z_STRVAL_P(p)); - Z_STRVAL_P(p) = colon; - } else { - Z_STRVAL_P(p) = colon + 1; + actual = estrndup(actual, actual_len); + Z_STRVAL_P(p) = actual; + Z_STRLEN_P(p) = actual_len; } - } else { - char *save = actual, *slash; - int actual_len = Z_STRLEN_P(p); - if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) && (slash = (char *)zend_memrchr(actual, '\\', actual_len))) { - actual = slash + 1; - actual_len -= (actual - Z_STRVAL_P(p)); - if (inline_change) { - actual = estrndup(actual, actual_len); - Z_STRVAL_P(p) = actual; - Z_STRLEN_P(p) = actual_len; - } + } + if (actual[0] == '\\') { + if (inline_change) { + memmove(Z_STRVAL_P(p), Z_STRVAL_P(p)+1, Z_STRLEN_P(p)); + --Z_STRLEN_P(p); + } else { + ++actual; } - if (actual[0] == '\\') { - if (inline_change) { - memmove(Z_STRVAL_P(p), Z_STRVAL_P(p)+1, Z_STRLEN_P(p)--); - } else { - ++actual; - } - --actual_len; + --actual_len; + } + if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) { + int fix_save = 0; + if (save[0] == '\\') { + save++; + fix_save = 1; } - if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) { - int fix_save = 0; - if (save[0] == '\\') { - save++; - fix_save = 1; - } - zend_error(E_ERROR, "Undefined constant '%s'", save); - if (fix_save) { - save--; - } - if (inline_change) { - str_efree(save); - } - save = NULL; + zend_error(E_ERROR, "Undefined constant '%s'", save); + if (fix_save) { + save--; } - if (inline_change && save && save != actual) { + if (inline_change) { str_efree(save); } - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); - p->type = IS_STRING; - if (!inline_change) { - Z_STRVAL_P(p) = actual; - Z_STRLEN_P(p) = actual_len; - zval_copy_ctor(p); - } + save = NULL; } - } else { - if (inline_change) { - str_efree(Z_STRVAL_P(p)); + if (inline_change && save && save != actual) { + str_efree(save); } - *p = const_value; + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); + p->type = IS_STRING; + if (!inline_change) { + Z_STRVAL_P(p) = actual; + Z_STRLEN_P(p) = actual_len; + zval_copy_ctor(p); + } + } + } else { + if (inline_change) { + str_efree(Z_STRVAL_P(p)); } + *p = const_value; + } - Z_SET_REFCOUNT_P(p, refcount); - Z_SET_ISREF_TO_P(p, is_ref); + Z_SET_REFCOUNT_P(p, refcount); + Z_SET_ISREF_TO_P(p, is_ref); + } else if (Z_TYPE_P(p) == IS_CONSTANT_ARRAY) { + zval **element, *new_val; + char *str_index; + uint str_index_len; + ulong num_index; + int ret; + + SEPARATE_ZVAL_IF_NOT_REF(pp); + p = *pp; + Z_TYPE_P(p) = IS_ARRAY; + + if (!inline_change) { + zval *tmp; + HashTable *tmp_ht = NULL; + + ALLOC_HASHTABLE(tmp_ht); + zend_hash_init(tmp_ht, zend_hash_num_elements(Z_ARRVAL_P(p)), NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(tmp_ht, Z_ARRVAL_P(p), (copy_ctor_func_t) zval_deep_copy, (void *) &tmp, sizeof(zval *)); + Z_ARRVAL_P(p) = tmp_ht; } - break; - - case IS_CONSTANT_ARRAY: { - zval **element, *new_val; - char *str_index; - uint str_index_len; - ulong num_index; - int ret; - - SEPARATE_ZVAL_IF_NOT_REF(pp); - p = *pp; - Z_TYPE_P(p) = IS_ARRAY; - - if (!inline_change) { - zval *tmp; - HashTable *tmp_ht = NULL; - - ALLOC_HASHTABLE(tmp_ht); - zend_hash_init(tmp_ht, zend_hash_num_elements(Z_ARRVAL_P(p)), NULL, ZVAL_PTR_DTOR, 0); - zend_hash_copy(tmp_ht, Z_ARRVAL_P(p), (copy_ctor_func_t) zval_deep_copy, (void *) &tmp, sizeof(zval *)); - Z_ARRVAL_P(p) = tmp_ht; - } - /* First go over the array and see if there are any constant indices */ - zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); - while (zend_hash_get_current_data(Z_ARRVAL_P(p), (void **) &element) == SUCCESS) { - if (!(Z_TYPE_PP(element) & IS_CONSTANT_INDEX)) { - zend_hash_move_forward(Z_ARRVAL_P(p)); - continue; - } - Z_TYPE_PP(element) &= ~IS_CONSTANT_INDEX; - if (zend_hash_get_current_key_ex(Z_ARRVAL_P(p), &str_index, &str_index_len, &num_index, 0, NULL) != HASH_KEY_IS_STRING) { - zend_hash_move_forward(Z_ARRVAL_P(p)); - continue; - } - if (str_index[str_index_len - 2] == IS_CONSTANT_AST) { - zend_ast_evaluate(&const_value, *(zend_ast **)str_index TSRMLS_CC); - ZEND_AST_DEL_REF(*(zend_ast **)str_index); - } else if (!zend_get_constant_ex(str_index, str_index_len - 3, &const_value, scope, str_index[str_index_len - 2] TSRMLS_CC)) { - char *actual; - const char *save = str_index; - if ((colon = (char*)zend_memrchr(str_index, ':', str_index_len - 3))) { - zend_error(E_ERROR, "Undefined class constant '%s'", str_index); - str_index_len -= ((colon - str_index) + 1); - str_index = colon; - } else { - if (str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) { - if ((actual = (char *)zend_memrchr(str_index, '\\', str_index_len - 3))) { - actual++; - str_index_len -= (actual - str_index); - str_index = actual; - } - } - if (str_index[0] == '\\') { - ++str_index; - --str_index_len; - } - if (save[0] == '\\') { - ++save; - } - if ((str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) == 0) { - zend_error(E_ERROR, "Undefined constant '%s'", save); + /* First go over the array and see if there are any constant indices */ + zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); + while (zend_hash_get_current_data(Z_ARRVAL_P(p), (void **) &element) == SUCCESS) { + if (!(Z_TYPE_PP(element) & IS_CONSTANT_INDEX)) { + zend_hash_move_forward(Z_ARRVAL_P(p)); + continue; + } + Z_TYPE_PP(element) &= ~IS_CONSTANT_INDEX; + if (zend_hash_get_current_key_ex(Z_ARRVAL_P(p), &str_index, &str_index_len, &num_index, 0, NULL) != HASH_KEY_IS_STRING) { + zend_hash_move_forward(Z_ARRVAL_P(p)); + continue; + } + if (str_index[str_index_len - 2] == IS_CONSTANT_AST) { + zend_ast_evaluate(&const_value, *(zend_ast **)str_index TSRMLS_CC); + zend_ast_destroy(*(zend_ast **)str_index); + } else if (!zend_get_constant_ex(str_index, str_index_len - 3, &const_value, scope, str_index[str_index_len - 2] TSRMLS_CC)) { + char *actual; + const char *save = str_index; + if ((colon = (char*)zend_memrchr(str_index, ':', str_index_len - 3))) { + zend_error(E_ERROR, "Undefined class constant '%s'", str_index); + str_index_len -= ((colon - str_index) + 1); + str_index = colon; + } else { + if (str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) { + if ((actual = (char *)zend_memrchr(str_index, '\\', str_index_len - 3))) { + actual++; + str_index_len -= (actual - str_index); + str_index = actual; } - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str_index, str_index); } - ZVAL_STRINGL(&const_value, str_index, str_index_len-3, 1); + if (str_index[0] == '\\') { + ++str_index; + --str_index_len; + } + if (save[0] == '\\') { + ++save; + } + if ((str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) == 0) { + zend_error(E_ERROR, "Undefined constant '%s'", save); + } + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str_index, str_index); } + ZVAL_STRINGL(&const_value, str_index, str_index_len-3, 1); + } - if (Z_REFCOUNT_PP(element) > 1) { - ALLOC_ZVAL(new_val); - *new_val = **element; - zval_copy_ctor(new_val); - Z_SET_REFCOUNT_P(new_val, 1); - Z_UNSET_ISREF_P(new_val); - - /* preserve this bit for inheritance */ - Z_TYPE_PP(element) |= IS_CONSTANT_INDEX; - zval_ptr_dtor(element); - *element = new_val; - } + if (Z_REFCOUNT_PP(element) > 1) { + ALLOC_ZVAL(new_val); + *new_val = **element; + zval_copy_ctor(new_val); + Z_SET_REFCOUNT_P(new_val, 1); + Z_UNSET_ISREF_P(new_val); + + /* preserve this bit for inheritance */ + Z_TYPE_PP(element) |= IS_CONSTANT_INDEX; + zval_ptr_dtor(element); + *element = new_val; + } - switch (Z_TYPE(const_value)) { - case IS_STRING: - ret = zend_symtable_update_current_key(Z_ARRVAL_P(p), Z_STRVAL(const_value), Z_STRLEN(const_value) + 1, HASH_UPDATE_KEY_IF_BEFORE); - break; - case IS_BOOL: - case IS_LONG: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, Z_LVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL); - break; - case IS_DOUBLE: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, zend_dval_to_lval(Z_DVAL(const_value)), HASH_UPDATE_KEY_IF_BEFORE, NULL); - break; - case IS_NULL: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, "", 1, 0, HASH_UPDATE_KEY_IF_BEFORE, NULL); - break; - default: - ret = SUCCESS; - break; - } - if (ret == SUCCESS) { - zend_hash_move_forward(Z_ARRVAL_P(p)); - } - zval_dtor(&const_value); + switch (Z_TYPE(const_value)) { + case IS_STRING: + ret = zend_symtable_update_current_key(Z_ARRVAL_P(p), Z_STRVAL(const_value), Z_STRLEN(const_value) + 1, HASH_UPDATE_KEY_IF_BEFORE); + break; + case IS_BOOL: + case IS_LONG: + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, Z_LVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL); + break; + case IS_DOUBLE: + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, zend_dval_to_lval(Z_DVAL(const_value)), HASH_UPDATE_KEY_IF_BEFORE, NULL); + break; + case IS_NULL: + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, "", 1, 0, HASH_UPDATE_KEY_IF_BEFORE, NULL); + break; + default: + ret = SUCCESS; + break; + } + if (ret == SUCCESS) { + zend_hash_move_forward(Z_ARRVAL_P(p)); } - zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC); - zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); + zval_dtor(&const_value); } - break; - - case IS_CONSTANT_AST: { - zend_ast *ast = Z_AST_P(p); - - zend_ast_evaluate(p, ast TSRMLS_CC); - ZEND_AST_DEL_REF(ast); + zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC); + zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); + } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) { + SEPARATE_ZVAL_IF_NOT_REF(pp); + p = *pp; + + zend_ast_evaluate(&const_value, Z_AST_P(p) TSRMLS_CC); + if (inline_change) { + zend_ast_destroy(Z_AST_P(p)); } + ZVAL_COPY_VALUE(p, &const_value); } return 0; } -- cgit v1.2.1 From 2d31eadbbf147a157cb4a0c89adaf30fee7371f0 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 29 Nov 2013 12:53:02 +0400 Subject: Added validation of class names in the autoload process --- Zend/zend_execute_API.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 6fa7e9bafb..93746b799f 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1081,6 +1081,14 @@ ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_ return FAILURE; } + /* Verify class name before passing it to __autoload() */ + if (strspn(name, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\") != name_length) { + if (!key) { + free_alloca(lc_free, use_heap); + } + return FAILURE; + } + if (EG(in_autoload) == NULL) { ALLOC_HASHTABLE(EG(in_autoload)); zend_hash_init(EG(in_autoload), 0, NULL, NULL, 0); -- cgit v1.2.1 From 5a87b7ff39bbf427807c46d1e51e2654259ad394 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 10 Dec 2013 14:19:17 +0400 Subject: Fixed bug #66252 (Problems in AST evaluation invalidating valid parent:: reference. Constant expessions have to be evaluated in context of defining class). --- Zend/zend_execute_API.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index bcce7418d5..82689ed7d6 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -593,7 +593,7 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco continue; } if (str_index[str_index_len - 2] == IS_CONSTANT_AST) { - zend_ast_evaluate(&const_value, *(zend_ast **)str_index TSRMLS_CC); + zend_ast_evaluate(&const_value, *(zend_ast **)str_index, scope TSRMLS_CC); zend_ast_destroy(*(zend_ast **)str_index); } else if (!zend_get_constant_ex(str_index, str_index_len - 3, &const_value, scope, str_index[str_index_len - 2] TSRMLS_CC)) { char *actual; @@ -667,7 +667,7 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco SEPARATE_ZVAL_IF_NOT_REF(pp); p = *pp; - zend_ast_evaluate(&const_value, Z_AST_P(p) TSRMLS_CC); + zend_ast_evaluate(&const_value, Z_AST_P(p), scope TSRMLS_CC); if (inline_change) { zend_ast_destroy(Z_AST_P(p)); } -- cgit v1.2.1 From d14670ccdb2782abaaaa721d1c379138fa64aae6 Mon Sep 17 00:00:00 2001 From: Kalle Sommer Nielsen Date: Wed, 18 Dec 2013 07:25:05 +0100 Subject: Eliminate another TSRMLS_FETCH() in i_zend_is_true() # Affected extensions have all been updated, ext/opcache and ext/zip # both have macros for cross version compatibility --- Zend/zend_execute_API.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 82689ed7d6..9c57300c84 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -443,9 +443,9 @@ ZEND_API void _zval_internal_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC) /* {{{ } /* }}} */ -ZEND_API int zend_is_true(zval *op) /* {{{ */ +ZEND_API int zend_is_true(zval *op TSRMLS_DC) /* {{{ */ { - return i_zend_is_true(op); + return i_zend_is_true(op TSRMLS_CC); } /* }}} */ -- cgit v1.2.1 From c0d060f5c02db168f1de895b41afffbc6e3cacfb Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Fri, 3 Jan 2014 11:04:26 +0800 Subject: Bump year --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 93746b799f..e79abdc944 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) | + | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) | +----------------------------------------------------------------------+ | This source file is subject to version 2.00 of the Zend license, | | that is bundled with this package in the file LICENSE, and is | -- cgit v1.2.1 From 47c902777297ce895aa915c13efdb00881af3669 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Fri, 3 Jan 2014 11:06:16 +0800 Subject: Bump year --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 3cc8b10083..45ad5c38bf 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) | + | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) | +----------------------------------------------------------------------+ | This source file is subject to version 2.00 of the Zend license, | | that is bundled with this package in the file LICENSE, and is | -- cgit v1.2.1 From c081ce628f0d76d44784d7bb8e06428b06142ac0 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Fri, 3 Jan 2014 11:08:10 +0800 Subject: Bump year --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 82689ed7d6..5d5153dc13 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | Zend Engine | +----------------------------------------------------------------------+ - | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) | + | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) | +----------------------------------------------------------------------+ | This source file is subject to version 2.00 of the Zend license, | | that is bundled with this package in the file LICENSE, and is | -- cgit v1.2.1 From f4cfaf36e23ca47da3e352e1c60909104c059647 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 10 Feb 2014 10:04:30 +0400 Subject: Use better data structures (incomplete) --- Zend/zend_execute_API.c | 615 ++++++++++++++++++++++-------------------------- 1 file changed, 278 insertions(+), 337 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 3988074779..c2be5c90c3 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -26,7 +26,7 @@ #include "zend_compile.h" #include "zend_execute.h" #include "zend_API.h" -#include "zend_ptr_stack.h" +#include "zend_stack.h" #include "zend_constants.h" #include "zend_extensions.h" #include "zend_exceptions.h" @@ -42,8 +42,8 @@ ZEND_API void (*zend_execute_ex)(zend_execute_data *execute_data TSRMLS_DC); ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC); /* true globals */ -ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0 }; -ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, NULL }; +//???ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0 }; +//???ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, NULL }; #ifdef ZEND_WIN32 #include @@ -131,17 +131,14 @@ void init_executor(TSRMLS_D) /* {{{ */ { zend_init_fpu(TSRMLS_C); - INIT_ZVAL(EG(uninitialized_zval)); + ZVAL_NULL(&EG(uninitialized_zval)); /* trick to make uninitialized_zval never be modified, passed by ref, etc. */ - Z_ADDREF(EG(uninitialized_zval)); - INIT_ZVAL(EG(error_zval)); - EG(uninitialized_zval_ptr)=&EG(uninitialized_zval); - EG(error_zval_ptr)=&EG(error_zval); + ZVAL_NULL(&EG(error_zval)); /* destroys stack frame, therefore makes core dumps worthless */ #if 0&&ZEND_DEBUG original_sigsegv_handler = signal(SIGSEGV, zend_handle_sigsegv); #endif - EG(return_value_ptr_ptr) = NULL; +//??? EG(return_value_ptr_ptr) = NULL; EG(symtable_cache_ptr) = EG(symtable_cache) - 1; EG(symtable_cache_limit) = EG(symtable_cache) + SYMTABLE_CACHE_SIZE - 1; @@ -158,8 +155,8 @@ void init_executor(TSRMLS_D) /* {{{ */ zend_vm_stack_init(TSRMLS_C); zend_vm_stack_push((void *) NULL TSRMLS_CC); - zend_hash_init(&EG(symbol_table), 50, NULL, ZVAL_PTR_DTOR, 0); - EG(active_symbol_table) = &EG(symbol_table); + zend_hash_init(&EG(symbol_table).ht, 50, NULL, ZVAL_PTR_DTOR, 0); + EG(active_symbol_table) = &EG(symbol_table).ht; zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator TSRMLS_CC); EG(opline_ptr) = NULL; @@ -168,13 +165,13 @@ void init_executor(TSRMLS_D) /* {{{ */ EG(ticks_count) = 0; - EG(user_error_handler) = NULL; + ZVAL_UNDEF(&EG(user_error_handler)); EG(current_execute_data) = NULL; zend_stack_init(&EG(user_error_handlers_error_reporting)); - zend_ptr_stack_init(&EG(user_error_handlers)); - zend_ptr_stack_init(&EG(user_exception_handlers)); + zend_stack_init(&EG(user_error_handlers)); + zend_stack_init(&EG(user_exception_handlers)); zend_objects_store_init(&EG(objects_store), 1024); @@ -189,7 +186,7 @@ void init_executor(TSRMLS_D) /* {{{ */ EG(scope) = NULL; EG(called_scope) = NULL; - EG(This) = NULL; + ZVAL_UNDEF(&EG(This)); EG(active_op_array) = NULL; @@ -198,9 +195,9 @@ void init_executor(TSRMLS_D) /* {{{ */ } /* }}} */ -static int zval_call_destructor(zval **zv TSRMLS_DC) /* {{{ */ +static int zval_call_destructor(zval *zv TSRMLS_DC) /* {{{ */ { - if (Z_TYPE_PP(zv) == IS_OBJECT && Z_REFCOUNT_PP(zv) == 1) { + if (Z_TYPE_P(zv) == IS_OBJECT && Z_REFCOUNT_P(zv) == 1) { return ZEND_HASH_APPLY_REMOVE; } else { return ZEND_HASH_APPLY_KEEP; @@ -213,9 +210,9 @@ void shutdown_destructors(TSRMLS_D) /* {{{ */ zend_try { int symbols; do { - symbols = zend_hash_num_elements(&EG(symbol_table)); - zend_hash_reverse_apply(&EG(symbol_table), (apply_func_t) zval_call_destructor TSRMLS_CC); - } while (symbols != zend_hash_num_elements(&EG(symbol_table))); + symbols = zend_hash_num_elements(&EG(symbol_table).ht); + zend_hash_reverse_apply(&EG(symbol_table).ht, (apply_func_t) zval_call_destructor TSRMLS_CC); + } while (symbols != zend_hash_num_elements(&EG(symbol_table).ht)); zend_objects_store_call_destructors(&EG(objects_store) TSRMLS_CC); } zend_catch { /* if we couldn't destruct cleanly, mark all objects as destructed anyway */ @@ -244,29 +241,29 @@ void shutdown_executor(TSRMLS_D) /* {{{ */ } */ zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator TSRMLS_CC); - zend_hash_graceful_reverse_destroy(&EG(symbol_table)); + zend_hash_graceful_reverse_destroy(&EG(symbol_table).ht); } zend_end_try(); zend_try { zval *zeh; /* remove error handlers before destroying classes and functions, * so that if handler used some class, crash would not happen */ - if (EG(user_error_handler)) { - zeh = EG(user_error_handler); - EG(user_error_handler) = NULL; - zval_ptr_dtor(&zeh); + if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) { + zeh = &EG(user_error_handler); + ZVAL_UNDEF(&EG(user_error_handler)); + zval_ptr_dtor(zeh); } - if (EG(user_exception_handler)) { - zeh = EG(user_exception_handler); - EG(user_exception_handler) = NULL; - zval_ptr_dtor(&zeh); + if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) { + zeh = &EG(user_exception_handler); + ZVAL_UNDEF(&EG(user_exception_handler)); + zval_ptr_dtor(zeh); } zend_stack_destroy(&EG(user_error_handlers_error_reporting)); zend_stack_init(&EG(user_error_handlers_error_reporting)); - zend_ptr_stack_clean(&EG(user_error_handlers), ZVAL_DESTRUCTOR, 1); - zend_ptr_stack_clean(&EG(user_exception_handlers), ZVAL_DESTRUCTOR, 1); + zend_stack_clean(&EG(user_error_handlers), (void (*)(void *))ZVAL_DESTRUCTOR, 1); + zend_stack_clean(&EG(user_exception_handlers), (void (*)(void *))ZVAL_DESTRUCTOR, 1); } zend_end_try(); zend_try { @@ -322,8 +319,8 @@ void shutdown_executor(TSRMLS_D) /* {{{ */ zend_hash_destroy(&EG(included_files)); zend_stack_destroy(&EG(user_error_handlers_error_reporting)); - zend_ptr_stack_destroy(&EG(user_error_handlers)); - zend_ptr_stack_destroy(&EG(user_exception_handlers)); + zend_stack_destroy(&EG(user_error_handlers)); + zend_stack_destroy(&EG(user_exception_handlers)); zend_objects_store_destroy(&EG(objects_store)); if (EG(in_autoload)) { zend_hash_destroy(EG(in_autoload)); @@ -355,7 +352,7 @@ ZEND_API const char *get_active_class_name(const char **space TSRMLS_DC) /* {{{ if (space) { *space = ce ? "::" : ""; } - return ce ? ce->name : ""; + return ce ? ce->name->val : ""; } default: if (space) { @@ -373,7 +370,7 @@ ZEND_API const char *get_active_function_name(TSRMLS_D) /* {{{ */ } switch (EG(current_execute_data)->function_state.function->type) { case ZEND_USER_FUNCTION: { - const char *function_name = ((zend_op_array *) EG(current_execute_data)->function_state.function)->function_name; + const char *function_name = ((zend_op_array *) EG(current_execute_data)->function_state.function)->function_name->val; if (function_name) { return function_name; @@ -383,7 +380,7 @@ ZEND_API const char *get_active_function_name(TSRMLS_D) /* {{{ */ } break; case ZEND_INTERNAL_FUNCTION: - return ((zend_internal_function *) EG(current_execute_data)->function_state.function)->function_name; + return ((zend_internal_function *) EG(current_execute_data)->function_state.function)->function_name->val; break; default: return NULL; @@ -394,7 +391,7 @@ ZEND_API const char *get_active_function_name(TSRMLS_D) /* {{{ */ ZEND_API const char *zend_get_executed_filename(TSRMLS_D) /* {{{ */ { if (EG(active_op_array)) { - return EG(active_op_array)->filename; + return EG(active_op_array)->filename->val; } else { return "[no active file]"; } @@ -421,24 +418,23 @@ ZEND_API zend_bool zend_is_executing(TSRMLS_D) /* {{{ */ } /* }}} */ -ZEND_API void _zval_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC) /* {{{ */ +ZEND_API void _zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ */ { TSRMLS_FETCH(); - i_zval_ptr_dtor(*zval_ptr ZEND_FILE_LINE_RELAY_CC TSRMLS_CC); + i_zval_ptr_dtor(zval_ptr ZEND_FILE_LINE_RELAY_CC TSRMLS_CC); } /* }}} */ -ZEND_API void _zval_internal_ptr_dtor(zval **zval_ptr ZEND_FILE_LINE_DC) /* {{{ */ +ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ */ { -#if DEBUG_ZEND>=2 - printf("Reducing refcount for %x (%x): %d->%d\n", *zval_ptr, zval_ptr, Z_REFCOUNT_PP(zval_ptr), Z_REFCOUNT_PP(zval_ptr) - 1); -#endif - Z_DELREF_PP(zval_ptr); - if (Z_REFCOUNT_PP(zval_ptr) == 0) { - zval_internal_dtor(*zval_ptr); - free(*zval_ptr); - } else if (Z_REFCOUNT_PP(zval_ptr) == 1) { - Z_UNSET_ISREF_PP(zval_ptr); + Z_DELREF_P(zval_ptr); + if (Z_REFCOUNT_P(zval_ptr) == 0) { + zval_internal_dtor(zval_ptr); + } else if (Z_REFCOUNT_P(zval_ptr) == 1) { +//??? Z_UNSET_ISREF_P(zval_ptr); + zend_reference *ref = Z_REF_P(zval_ptr); + ZVAL_COPY_VALUE(zval_ptr, Z_REFVAL_P(zval_ptr)); + efree(ref); } } /* }}} */ @@ -456,22 +452,19 @@ ZEND_API int zend_is_true(zval *op TSRMLS_DC) /* {{{ */ #define Z_REAL_TYPE_P(p) (Z_TYPE_P(p) & ~IS_VISITED_CONSTANT) #define MARK_CONSTANT_VISITED(p) Z_TYPE_P(p) |= IS_VISITED_CONSTANT -static void zval_deep_copy(zval **p) +static void zval_deep_copy(zval *p) { - zval *value; - - ALLOC_ZVAL(value); - *value = **p; - Z_TYPE_P(value) &= ~IS_CONSTANT_INDEX; - zval_copy_ctor(value); - Z_TYPE_P(value) = Z_TYPE_PP(p); - INIT_PZVAL(value); - *p = value; + zval value; + + ZVAL_COPY_VALUE(&value, p); + Z_TYPE(value) &= ~IS_CONSTANT_INDEX; + zval_copy_ctor(&value); + Z_TYPE(value) = Z_TYPE_P(p); + ZVAL_COPY_VALUE(p, &value); } -ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC) /* {{{ */ +ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope TSRMLS_DC) /* {{{ */ { - zval *p = *pp; zend_bool inline_change = (zend_bool) (zend_uintptr_t) arg; zval const_value; char *colon; @@ -480,29 +473,28 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco zend_error(E_ERROR, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p)); } else if ((Z_TYPE_P(p) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { int refcount; - zend_uchar is_ref; +//??? zend_uchar is_ref; - SEPARATE_ZVAL_IF_NOT_REF(pp); - p = *pp; + SEPARATE_ZVAL_IF_NOT_REF(p); MARK_CONSTANT_VISITED(p); refcount = Z_REFCOUNT_P(p); - is_ref = Z_ISREF_P(p); +//??? is_ref = Z_ISREF_P(p); - if (!zend_get_constant_ex(p->value.str.val, p->value.str.len, &const_value, scope, Z_REAL_TYPE_P(p) TSRMLS_CC)) { + if (!zend_get_constant_ex(Z_STRVAL_P(p), Z_STRLEN_P(p), &const_value, scope, Z_REAL_TYPE_P(p) TSRMLS_CC)) { char *actual = Z_STRVAL_P(p); if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) { zend_error(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(p)); Z_STRLEN_P(p) -= ((colon - Z_STRVAL_P(p)) + 1); - if (inline_change) { - colon = estrndup(colon, Z_STRLEN_P(p)); - str_efree(Z_STRVAL_P(p)); - Z_STRVAL_P(p) = colon; - } else { - Z_STRVAL_P(p) = colon + 1; - } +//??? if (inline_change) { + zend_string *tmp = STR_INIT(colon, Z_STRLEN_P(p), 0); + STR_RELEASE(Z_STR_P(p)); + Z_STR_P(p) = tmp; +//??? } else { +//??? Z_STRVAL_P(p) = colon + 1; +//??? } } else { char *save = actual, *slash; int actual_len = Z_STRLEN_P(p); @@ -510,9 +502,9 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco actual = slash + 1; actual_len -= (actual - Z_STRVAL_P(p)); if (inline_change) { - actual = estrndup(actual, actual_len); - Z_STRVAL_P(p) = actual; - Z_STRLEN_P(p) = actual_len; + zend_string *s = STR_INIT(actual, actual_len, 0); + STR_RELEASE(Z_STR_P(p)); + Z_STR_P(p) = s; } } if (actual[0] == '\\') { @@ -534,64 +526,59 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco if (fix_save) { save--; } - if (inline_change) { - str_efree(save); - } +//??? if (inline_change) { +//??? str_efree(save); +//??? } save = NULL; } - if (inline_change && save && save != actual) { - str_efree(save); - } +//??? if (inline_change && save && save != actual) { +//??? str_efree(save); +//??? } zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); p->type = IS_STRING; if (!inline_change) { - Z_STRVAL_P(p) = actual; - Z_STRLEN_P(p) = actual_len; - zval_copy_ctor(p); + ZVAL_STRINGL(p, actual, actual_len); } } } else { - if (inline_change) { - str_efree(Z_STRVAL_P(p)); - } +//??? if (inline_change) { +//??? str_efree(Z_STRVAL_P(p)); +//??? } *p = const_value; } Z_SET_REFCOUNT_P(p, refcount); - Z_SET_ISREF_TO_P(p, is_ref); +//??? Z_SET_ISREF_TO_P(p, is_ref); } else if (Z_TYPE_P(p) == IS_CONSTANT_ARRAY) { - zval **element, *new_val; - char *str_index; - uint str_index_len; + zval *element, new_val; + zend_string *str_index; ulong num_index; int ret; - SEPARATE_ZVAL_IF_NOT_REF(pp); - p = *pp; - Z_TYPE_P(p) = IS_ARRAY; + SEPARATE_ZVAL_IF_NOT_REF(p); + Z_TYPE_P(p) = IS_ARRAY; if (!inline_change) { - zval *tmp; - HashTable *tmp_ht = NULL; - - ALLOC_HASHTABLE(tmp_ht); - zend_hash_init(tmp_ht, zend_hash_num_elements(Z_ARRVAL_P(p)), NULL, ZVAL_PTR_DTOR, 0); - zend_hash_copy(tmp_ht, Z_ARRVAL_P(p), (copy_ctor_func_t) zval_deep_copy, (void *) &tmp, sizeof(zval *)); - Z_ARRVAL_P(p) = tmp_ht; + HashTable *ht = Z_ARRVAL_P(p); + ZVAL_NEW_ARR(p); + zend_hash_init(Z_ARRVAL_P(p), zend_hash_num_elements(ht), NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(Z_ARRVAL_P(p), ht, (copy_ctor_func_t) zval_deep_copy); } /* First go over the array and see if there are any constant indices */ zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); - while (zend_hash_get_current_data(Z_ARRVAL_P(p), (void **) &element) == SUCCESS) { - if (!(Z_TYPE_PP(element) & IS_CONSTANT_INDEX)) { + while ((element = zend_hash_get_current_data(Z_ARRVAL_P(p))) != NULL) { + if (!(Z_TYPE_P(element) & IS_CONSTANT_INDEX)) { zend_hash_move_forward(Z_ARRVAL_P(p)); continue; } - Z_TYPE_PP(element) &= ~IS_CONSTANT_INDEX; - if (zend_hash_get_current_key_ex(Z_ARRVAL_P(p), &str_index, &str_index_len, &num_index, 0, NULL) != HASH_KEY_IS_STRING) { + Z_TYPE_P(element) &= ~IS_CONSTANT_INDEX; + if (zend_hash_get_current_key_ex(Z_ARRVAL_P(p), &str_index, &num_index, 0, NULL) != HASH_KEY_IS_STRING) { zend_hash_move_forward(Z_ARRVAL_P(p)); continue; } +//??? +#if 0 if (str_index[str_index_len - 2] == IS_CONSTANT_AST) { zend_ast_evaluate(&const_value, *(zend_ast **)str_index, scope TSRMLS_CC); zend_ast_destroy(*(zend_ast **)str_index); @@ -624,33 +611,30 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco } ZVAL_STRINGL(&const_value, str_index, str_index_len-3, 1); } +#endif - if (Z_REFCOUNT_PP(element) > 1) { - ALLOC_ZVAL(new_val); - *new_val = **element; - zval_copy_ctor(new_val); - Z_SET_REFCOUNT_P(new_val, 1); - Z_UNSET_ISREF_P(new_val); + if (Z_REFCOUNT_P(element) > 1) { + ZVAL_DUP(&new_val, element); /* preserve this bit for inheritance */ - Z_TYPE_PP(element) |= IS_CONSTANT_INDEX; + Z_TYPE_P(element) |= IS_CONSTANT_INDEX; zval_ptr_dtor(element); - *element = new_val; + ZVAL_COPY_VALUE(element, &new_val); } switch (Z_TYPE(const_value)) { case IS_STRING: - ret = zend_symtable_update_current_key(Z_ARRVAL_P(p), Z_STRVAL(const_value), Z_STRLEN(const_value) + 1, HASH_UPDATE_KEY_IF_BEFORE); + ret = zend_symtable_update_current_key(Z_ARRVAL_P(p), Z_STR(const_value), HASH_UPDATE_KEY_IF_BEFORE); break; case IS_BOOL: case IS_LONG: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, Z_LVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL); + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, Z_LVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL); break; case IS_DOUBLE: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, zend_dval_to_lval(Z_DVAL(const_value)), HASH_UPDATE_KEY_IF_BEFORE, NULL); + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, zend_dval_to_lval(Z_DVAL(const_value)), HASH_UPDATE_KEY_IF_BEFORE, NULL); break; case IS_NULL: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, "", 1, 0, HASH_UPDATE_KEY_IF_BEFORE, NULL); + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, STR_EMPTY_ALLOC(), 0, HASH_UPDATE_KEY_IF_BEFORE, NULL); break; default: ret = SUCCESS; @@ -664,12 +648,11 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC); zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) { - SEPARATE_ZVAL_IF_NOT_REF(pp); - p = *pp; + SEPARATE_ZVAL_IF_NOT_REF(p); - zend_ast_evaluate(&const_value, Z_AST_P(p), scope TSRMLS_CC); + zend_ast_evaluate(&const_value, Z_ASTVAL_P(p), scope TSRMLS_CC); if (inline_change) { - zend_ast_destroy(Z_AST_P(p)); + zend_ast_destroy(Z_ASTVAL_P(p)); } ZVAL_COPY_VALUE(p, &const_value); } @@ -677,45 +660,40 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco } /* }}} */ -ZEND_API int zval_update_constant_inline_change(zval **pp, void *scope TSRMLS_DC) /* {{{ */ +ZEND_API int zval_update_constant_inline_change(zval *pp, void *scope TSRMLS_DC) /* {{{ */ { return zval_update_constant_ex(pp, (void*)1, scope TSRMLS_CC); } /* }}} */ -ZEND_API int zval_update_constant_no_inline_change(zval **pp, void *scope TSRMLS_DC) /* {{{ */ +ZEND_API int zval_update_constant_no_inline_change(zval *pp, void *scope TSRMLS_DC) /* {{{ */ { return zval_update_constant_ex(pp, (void*)0, scope TSRMLS_CC); } /* }}} */ -ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC) /* {{{ */ +ZEND_API int zval_update_constant(zval *pp, void *arg TSRMLS_DC) /* {{{ */ { return zval_update_constant_ex(pp, arg, NULL TSRMLS_CC); } /* }}} */ -int call_user_function(HashTable *function_table, zval **object_pp, zval *function_name, zval *retval_ptr, zend_uint param_count, zval *params[] TSRMLS_DC) /* {{{ */ +int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, zend_uint param_count, zval params[] TSRMLS_DC) /* {{{ */ { - zval ***params_array; + zval *params_array; zend_uint i; int ex_retval; - zval *local_retval_ptr = NULL; if (param_count) { - params_array = (zval ***) emalloc(sizeof(zval **)*param_count); + params_array = (zval *) emalloc(sizeof(zval) * param_count); for (i=0; iretval_ptr_ptr = NULL; + fci->retval = NULL; if (!EG(active)) { return FAILURE; /* executor is already inactive */ @@ -779,7 +757,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS execute_data = *EG(current_execute_data); EX(op_array) = NULL; EX(opline) = NULL; - EX(object) = NULL; + ZVAL_UNDEF(&EX(object)); } else { /* This only happens when we're called outside any execute()'s * It shouldn't be strictly necessary to NULL execute_data out, @@ -796,7 +774,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS fci_cache = &fci_cache_local; } - if (!zend_is_callable_ex(fci->function_name, fci->object_ptr, IS_CALLABLE_CHECK_SILENT, &callable_name, NULL, fci_cache, &error TSRMLS_CC)) { + if (!zend_is_callable_ex(&fci->function_name, fci->object_ptr, IS_CALLABLE_CHECK_SILENT, &callable_name, NULL, fci_cache, &error TSRMLS_CC)) { if (error) { zend_error(E_WARNING, "Invalid callback %s, %s", callable_name, error); efree(error); @@ -820,11 +798,11 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS calling_scope = fci_cache->calling_scope; called_scope = fci_cache->called_scope; fci->object_ptr = fci_cache->object_ptr; - EX(object) = fci->object_ptr; - if (fci->object_ptr && Z_TYPE_P(fci->object_ptr) == IS_OBJECT && - (!EG(objects_store).object_buckets || !EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(fci->object_ptr)].valid)) { - return FAILURE; - } + ZVAL_COPY_VALUE(&EX(object), fci->object_ptr); +//??? if (fci->object_ptr && Z_TYPE_P(fci->object_ptr) == IS_OBJECT && +//??? (!EG(objects_store).object_buckets || !EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(fci->object_ptr)].valid)) { +//??? return FAILURE; +//??? } if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) { if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) { @@ -832,20 +810,20 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } if (EX(function_state).function->common.fn_flags & ZEND_ACC_DEPRECATED) { zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated", - EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name : "", + EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name->val : "", EX(function_state).function->common.scope ? "::" : "", - EX(function_state).function->common.function_name); + EX(function_state).function->common.function_name->val); } } ZEND_VM_STACK_GROW_IF_NEEDED(fci->param_count + 1); for (i=0; iparam_count; i++) { - zval *param; + zval *param, tmp; if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)) { - if (!PZVAL_IS_REF(*fci->params[i]) && Z_REFCOUNT_PP(fci->params[i]) > 1) { - zval *new_zval; + if (!Z_ISREF(fci->params[i]) && Z_REFCOUNT(fci->params[i]) > 1) { + zval new_zval; if (fci->no_separation && !ARG_MAY_BE_SENT_BY_REF(EX(function_state).function, i + 1)) { @@ -857,36 +835,30 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given", i+1, - EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name : "", + EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name->val : "", EX(function_state).function->common.scope ? "::" : "", - EX(function_state).function->common.function_name); + EX(function_state).function->common.function_name->val); return FAILURE; } - ALLOC_ZVAL(new_zval); - *new_zval = **fci->params[i]; - zval_copy_ctor(new_zval); - Z_SET_REFCOUNT_P(new_zval, 1); - Z_DELREF_PP(fci->params[i]); - *fci->params[i] = new_zval; + ZVAL_DUP(&new_zval, &fci->params[i]); + Z_DELREF(fci->params[i]); + ZVAL_COPY_VALUE(&fci->params[i], &new_zval); } - Z_ADDREF_PP(fci->params[i]); - Z_SET_ISREF_PP(fci->params[i]); - param = *fci->params[i]; - } else if (PZVAL_IS_REF(*fci->params[i]) && + Z_ADDREF(fci->params[i]); +//??? Z_SET_ISREF_PP(fci->params[i]); + param = &fci->params[i]; + } else if (Z_ISREF(fci->params[i]) && /* don't separate references for __call */ (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 ) { - ALLOC_ZVAL(param); - *param = **(fci->params[i]); - INIT_PZVAL(param); - zval_copy_ctor(param); - } else if (*fci->params[i] != &EG(uninitialized_zval)) { - Z_ADDREF_PP(fci->params[i]); - param = *fci->params[i]; - } else { - ALLOC_ZVAL(param); - *param = **(fci->params[i]); - INIT_PZVAL(param); + param = &tmp; + ZVAL_DUP(param, &fci->params[i]); +//??? } else if (*fci->params[i] != &EG(uninitialized_zval)) { + Z_ADDREF(fci->params[i]); + param = &fci->params[i]; +//??? } else { +//??? param = &tmp; +//??? ZVAL_COPY_VALUE(param, &fci->params[i]); } zend_vm_stack_push(param TSRMLS_CC); } @@ -897,7 +869,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS current_scope = EG(scope); EG(scope) = calling_scope; - current_this = EG(This); + ZVAL_COPY_VALUE(¤t_this, &EG(This)); current_called_scope = EG(called_scope); if (called_scope) { @@ -908,24 +880,24 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS if (fci->object_ptr) { if ((EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)) { - EG(This) = NULL; + ZVAL_UNDEF(&EG(This)); } else { - EG(This) = fci->object_ptr; + ZVAL_COPY_VALUE(&EG(This), fci->object_ptr); - if (!PZVAL_IS_REF(EG(This))) { - Z_ADDREF_P(EG(This)); /* For $this pointer */ + if (!Z_ISREF(EG(This))) { + Z_ADDREF(EG(This)); /* For $this pointer */ } else { - zval *this_ptr; - - ALLOC_ZVAL(this_ptr); - *this_ptr = *EG(This); - INIT_PZVAL(this_ptr); - zval_copy_ctor(this_ptr); - EG(This) = this_ptr; +//??? zval *this_ptr; +//??? +//??? ALLOC_ZVAL(this_ptr); +//??? *this_ptr = *EG(This); +//??? INIT_PZVAL(this_ptr); +//??? zval_copy_ctor(this_ptr); +//??? EG(This) = this_ptr; } } } else { - EG(This) = NULL; + ZVAL_UNDEF(&EG(This)); } EX(prev_execute_data) = EG(current_execute_data); @@ -940,14 +912,14 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EG(active_symbol_table) = NULL; } - original_return_value = EG(return_value_ptr_ptr); +//??? original_return_value = EG(return_value_ptr_ptr); original_op_array = EG(active_op_array); - EG(return_value_ptr_ptr) = fci->retval_ptr_ptr; +//??? EG(return_value_ptr_ptr) = fci->retval_ptr_ptr; EG(active_op_array) = (zend_op_array *) EX(function_state).function; original_opline_ptr = EG(opline_ptr); if (EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) { - *fci->retval_ptr_ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC); +//??? *fci->retval_ptr_ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC); } else { zend_execute(EG(active_op_array) TSRMLS_CC); } @@ -957,17 +929,17 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } EG(active_symbol_table) = calling_symbol_table; EG(active_op_array) = original_op_array; - EG(return_value_ptr_ptr)=original_return_value; +//??? EG(return_value_ptr_ptr)=original_return_value; EG(opline_ptr) = original_opline_ptr; } else if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { int call_via_handler = (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0; - ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr); +//??? ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr); if (EX(function_state).function->common.scope) { EG(scope) = EX(function_state).function->common.scope; } if (EXPECTED(zend_execute_internal == NULL)) { /* saves one function call if zend_execute_internal is not used */ - EX(function_state).function->internal_function.handler(fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC); + EX(function_state).function->internal_function.handler(fci->param_count, fci->retval, fci->object_ptr, 1 TSRMLS_CC); } else { zend_execute_internal(&execute_data, fci, 1 TSRMLS_CC); } @@ -977,9 +949,9 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS { INIT_PZVAL(*fci->retval_ptr_ptr); }*/ - if (EG(exception) && fci->retval_ptr_ptr) { - zval_ptr_dtor(fci->retval_ptr_ptr); - *fci->retval_ptr_ptr = NULL; + if (EG(exception) && fci->retval) { + zval_ptr_dtor(fci->retval); + ZVAL_UNDEF(fci->retval); } if (call_via_handler) { @@ -987,11 +959,11 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS fci_cache->initialized = 0; } } else { /* ZEND_OVERLOADED_FUNCTION */ - ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr); +//??? ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr); /* Not sure what should be done here if it's a static method */ if (fci->object_ptr) { - Z_OBJ_HT_P(fci->object_ptr)->call_method(EX(function_state).function->common.function_name, fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, fci->object_ptr, 1 TSRMLS_CC); + Z_OBJ_HT_P(fci->object_ptr)->call_method(EX(function_state).function->common.function_name, fci->param_count, fci->retval, fci->object_ptr, 1 TSRMLS_CC); } else { zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object"); } @@ -1001,19 +973,17 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } efree(EX(function_state).function); - if (EG(exception) && fci->retval_ptr_ptr) { - zval_ptr_dtor(fci->retval_ptr_ptr); - *fci->retval_ptr_ptr = NULL; + if (EG(exception) && fci->retval) { + zval_ptr_dtor(fci->retval); + ZVAL_UNDEF(fci->retval); } } zend_vm_stack_clear_multiple(0 TSRMLS_CC); - if (EG(This)) { - zval_ptr_dtor(&EG(This)); - } + zval_ptr_dtor(&EG(This)); EG(called_scope) = current_called_scope; EG(scope) = current_scope; - EG(This) = current_this; + ZVAL_COPY_VALUE(&EG(This), ¤t_this); EG(current_execute_data) = EX(prev_execute_data); if (EG(exception)) { @@ -1023,47 +993,38 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } /* }}} */ -ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_literal *key, int use_autoload, zend_class_entry ***ce TSRMLS_DC) /* {{{ */ +ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zend_literal *key, int use_autoload TSRMLS_DC) /* {{{ */ { - zval **args[1]; - zval autoload_function; - zval *class_name_ptr; - zval *retval_ptr = NULL; - int retval, lc_length; - char *lc_name; - char *lc_free; + zend_class_entry *ce = NULL; + zval args[1]; + zval local_retval; + int retval; + zend_string *lc_name; zend_fcall_info fcall_info; zend_fcall_info_cache fcall_cache; - char dummy = 1; - ulong hash; - ALLOCA_FLAG(use_heap) if (key) { - lc_name = Z_STRVAL(key->constant); - lc_length = Z_STRLEN(key->constant) + 1; - hash = key->hash_value; + lc_name = Z_STR(key->constant); } else { - if (name == NULL || !name_length) { - return FAILURE; + if (name == NULL || !name->len) { + return NULL; } - lc_free = lc_name = do_alloca(name_length + 1, use_heap); - zend_str_tolower_copy(lc_name, name, name_length); - lc_length = name_length + 1; - - if (lc_name[0] == '\\') { - lc_name += 1; - lc_length -= 1; + if (name->val[0] == '\\') { + lc_name = STR_ALLOC(name->len - 1, 0); + zend_str_tolower_copy(lc_name->val, name->val + 1, name->len - 1); + } else { + lc_name = STR_ALLOC(name->len, 0); + zend_str_tolower_copy(lc_name->val, name->val, name->len); } - - hash = zend_inline_hash_func(lc_name, lc_length); } - if (zend_hash_quick_find(EG(class_table), lc_name, lc_length, hash, (void **) ce) == SUCCESS) { + ce = zend_hash_find_ptr(EG(class_table), lc_name); + if (ce) { if (!key) { - free_alloca(lc_free, use_heap); + STR_FREE(lc_name); } - return SUCCESS; + return ce; } /* The compiler is not-reentrant. Make sure we __autoload() only during run-time @@ -1071,17 +1032,17 @@ ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_ */ if (!use_autoload || zend_is_compiling(TSRMLS_C)) { if (!key) { - free_alloca(lc_free, use_heap); + STR_FREE(lc_name); } - return FAILURE; + return NULL; } /* Verify class name before passing it to __autoload() */ - if (strspn(name, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\") != name_length) { + if (strspn(name->val, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\") != name->len) { if (!key) { - free_alloca(lc_free, use_heap); + STR_FREE(lc_name); } - return FAILURE; + return NULL; } if (EG(in_autoload) == NULL) { @@ -1089,30 +1050,26 @@ ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_ zend_hash_init(EG(in_autoload), 0, NULL, NULL, 0); } - if (zend_hash_quick_add(EG(in_autoload), lc_name, lc_length, hash, (void**)&dummy, sizeof(char), NULL) == FAILURE) { + if (zend_hash_add_empty_element(EG(in_autoload), lc_name) == NULL) { if (!key) { - free_alloca(lc_free, use_heap); + STR_FREE(lc_name); } - return FAILURE; + return NULL; } - ZVAL_STRINGL(&autoload_function, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1, 0); + ZVAL_UNDEF(&local_retval); - ALLOC_ZVAL(class_name_ptr); - INIT_PZVAL(class_name_ptr); - if (name[0] == '\\') { - ZVAL_STRINGL(class_name_ptr, name+1, name_length-1, 1); + if (name->val[0] == '\\') { + ZVAL_STRINGL(&args[0], name->val + 1, name->len - 1); } else { - ZVAL_STRINGL(class_name_ptr, name, name_length, 1); + ZVAL_STR(&args[0], STR_COPY(name)); } - args[0] = &class_name_ptr; - fcall_info.size = sizeof(fcall_info); fcall_info.function_table = EG(function_table); - fcall_info.function_name = &autoload_function; + ZVAL_STRINGL(&fcall_info.function_name, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1); fcall_info.symbol_table = NULL; - fcall_info.retval_ptr_ptr = &retval_ptr; + fcall_info.retval = &local_retval; fcall_info.param_count = 1; fcall_info.params = args; fcall_info.object_ptr = NULL; @@ -1130,27 +1087,25 @@ ZEND_API int zend_lookup_class_ex(const char *name, int name_length, const zend_ EG(autoload_func) = fcall_cache.function_handler; - zval_ptr_dtor(&class_name_ptr); + zval_ptr_dtor(&args[0]); - zend_hash_quick_del(EG(in_autoload), lc_name, lc_length, hash); + zend_hash_del(EG(in_autoload), lc_name); - if (retval_ptr) { - zval_ptr_dtor(&retval_ptr); - } + zval_ptr_dtor(&local_retval); if (retval == SUCCESS) { - retval = zend_hash_quick_find(EG(class_table), lc_name, lc_length, hash, (void **) ce); + ce = zend_hash_find_ptr(EG(class_table), lc_name); } if (!key) { - free_alloca(lc_free, use_heap); + STR_FREE(lc_name); } - return retval; + return ce; } /* }}} */ -ZEND_API int zend_lookup_class(const char *name, int name_length, zend_class_entry ***ce TSRMLS_DC) /* {{{ */ +ZEND_API zend_class_entry *zend_lookup_class(zend_string *name TSRMLS_DC) /* {{{ */ { - return zend_lookup_class_ex(name, name_length, NULL, 1, ce TSRMLS_CC); + return zend_lookup_class_ex(name, NULL, 1 TSRMLS_CC); } /* }}} */ @@ -1163,17 +1118,14 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s int retval; if (retval_ptr) { - Z_STRLEN(pv) = str_len + sizeof("return ;") - 1; - Z_STRVAL(pv) = emalloc(Z_STRLEN(pv) + 1); + ZVAL_STR(&pv, STR_ALLOC(str_len + sizeof("return ;"), 1)); memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1); memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, str, str_len); Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';'; Z_STRVAL(pv)[Z_STRLEN(pv)] = '\0'; } else { - Z_STRLEN(pv) = str_len; - Z_STRVAL(pv) = str; + ZVAL_STRINGL(&pv, str, str_len); } - Z_TYPE(pv) = IS_STRING; /*printf("Evaluating '%s'\n", pv.value.str.val);*/ @@ -1183,12 +1135,12 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s CG(compiler_options) = original_compiler_options; if (new_op_array) { - zval *local_retval_ptr=NULL; - zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr); +//??? zval *local_retval_ptr=NULL; +//??? zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr); zend_op **original_opline_ptr = EG(opline_ptr); int orig_interactive = CG(interactive); - EG(return_value_ptr_ptr) = &local_retval_ptr; +//??? EG(return_value_ptr_ptr) = &local_retval_ptr; EG(active_op_array) = new_op_array; EG(no_extensions)=1; if (!EG(active_symbol_table)) { @@ -1205,24 +1157,24 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s } zend_end_try(); CG(interactive) = orig_interactive; - if (local_retval_ptr) { - if (retval_ptr) { - COPY_PZVAL_TO_ZVAL(*retval_ptr, local_retval_ptr); - } else { - zval_ptr_dtor(&local_retval_ptr); - } - } else { - if (retval_ptr) { - INIT_ZVAL(*retval_ptr); - } - } +//??? if (local_retval_ptr) { +//??? if (retval_ptr) { +//??? COPY_PZVAL_TO_ZVAL(*retval_ptr, local_retval_ptr); +//??? } else { +//??? zval_ptr_dtor(&local_retval_ptr); +//??? } +//??? } else { +//??? if (retval_ptr) { +//??? INIT_ZVAL(*retval_ptr); +//??? } +//??? } EG(no_extensions)=0; EG(opline_ptr) = original_opline_ptr; EG(active_op_array) = original_active_op_array; destroy_op_array(new_op_array TSRMLS_CC); efree(new_op_array); - EG(return_value_ptr_ptr) = original_return_value_ptr_ptr; +//??? EG(return_value_ptr_ptr) = original_return_value_ptr_ptr; retval = SUCCESS; } else { retval = FAILURE; @@ -1316,7 +1268,7 @@ void execute_new_code(TSRMLS_D) /* {{{ */ zend_release_labels(1 TSRMLS_CC); - EG(return_value_ptr_ptr) = NULL; +//??? EG(return_value_ptr_ptr) = NULL; EG(active_op_array) = CG(active_op_array); orig_interactive = CG(interactive); CG(interactive) = 0; @@ -1545,9 +1497,9 @@ void zend_unset_timeout(TSRMLS_D) /* {{{ */ } /* }}} */ -zend_class_entry *zend_fetch_class(const char *class_name, uint class_name_len, int fetch_type TSRMLS_DC) /* {{{ */ +zend_class_entry *zend_fetch_class(zend_string *class_name, int fetch_type TSRMLS_DC) /* {{{ */ { - zend_class_entry **pce; + zend_class_entry *ce; int use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) == 0; int silent = (fetch_type & ZEND_FETCH_CLASS_SILENT) != 0; @@ -1574,7 +1526,7 @@ check_fetch_type: } return EG(called_scope); case ZEND_FETCH_CLASS_AUTO: { - fetch_type = zend_get_class_fetch_type(class_name, class_name_len); + fetch_type = zend_get_class_fetch_type(class_name->val, class_name->len); if (fetch_type!=ZEND_FETCH_CLASS_DEFAULT) { goto check_fetch_type; } @@ -1582,44 +1534,44 @@ check_fetch_type: break; } - if (zend_lookup_class_ex(class_name, class_name_len, NULL, use_autoload, &pce TSRMLS_CC) == FAILURE) { + if ((ce = zend_lookup_class_ex(class_name, NULL, use_autoload TSRMLS_CC)) == NULL) { if (use_autoload) { if (!silent && !EG(exception)) { if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) { - zend_error(E_ERROR, "Interface '%s' not found", class_name); + zend_error(E_ERROR, "Interface '%s' not found", class_name->val); } else if (fetch_type == ZEND_FETCH_CLASS_TRAIT) { - zend_error(E_ERROR, "Trait '%s' not found", class_name); + zend_error(E_ERROR, "Trait '%s' not found", class_name->val); } else { - zend_error(E_ERROR, "Class '%s' not found", class_name); + zend_error(E_ERROR, "Class '%s' not found", class_name->val); } } } return NULL; } - return *pce; + return ce; } /* }}} */ -zend_class_entry *zend_fetch_class_by_name(const char *class_name, uint class_name_len, const zend_literal *key, int fetch_type TSRMLS_DC) /* {{{ */ +zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, const zend_literal *key, int fetch_type TSRMLS_DC) /* {{{ */ { - zend_class_entry **pce; + zend_class_entry *ce; int use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) == 0; - if (zend_lookup_class_ex(class_name, class_name_len, key, use_autoload, &pce TSRMLS_CC) == FAILURE) { + if ((ce = zend_lookup_class_ex(class_name, key, use_autoload TSRMLS_CC)) == NULL) { if (use_autoload) { if ((fetch_type & ZEND_FETCH_CLASS_SILENT) == 0 && !EG(exception)) { if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_INTERFACE) { - zend_error(E_ERROR, "Interface '%s' not found", class_name); + zend_error(E_ERROR, "Interface '%s' not found", class_name->val); } else if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_TRAIT) { - zend_error(E_ERROR, "Trait '%s' not found", class_name); + zend_error(E_ERROR, "Trait '%s' not found", class_name->val); } else { - zend_error(E_ERROR, "Class '%s' not found", class_name); + zend_error(E_ERROR, "Class '%s' not found", class_name->val); } } } return NULL; } - return *pce; + return ce; } /* }}} */ @@ -1628,7 +1580,7 @@ zend_class_entry *zend_fetch_class_by_name(const char *class_name, uint class_na #define DISPLAY_ABSTRACT_FN(idx) \ ai.afn[idx] ? ZEND_FN_SCOPE_NAME(ai.afn[idx]) : "", \ ai.afn[idx] ? "::" : "", \ - ai.afn[idx] ? ai.afn[idx]->common.function_name : "", \ + ai.afn[idx] ? ai.afn[idx]->common.function_name->val : "", \ ai.afn[idx] && ai.afn[idx + 1] ? ", " : (ai.afn[idx] && ai.cnt > MAX_ABSTRACT_INFO_CNT ? ", ..." : "") typedef struct _zend_abstract_info { @@ -1669,7 +1621,7 @@ void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC) /* {{{ */ if (ai.cnt) { zend_error(E_ERROR, "Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")", - ce->name, ai.cnt, + ce->name->val, ai.cnt, ai.cnt > 1 ? "s" : "", DISPLAY_ABSTRACT_FN(0), DISPLAY_ABSTRACT_FN(1), @@ -1688,26 +1640,25 @@ ZEND_API void zend_reset_all_cv(HashTable *symbol_table TSRMLS_DC) /* {{{ */ for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) { if (ex->op_array && ex->symbol_table == symbol_table) { for (i = 0; i < ex->op_array->last_var; i++) { - *EX_CV_NUM(ex, i) = NULL; + ZVAL_UNDEF(EX_VAR_NUM_2(ex, i)); } } } } /* }}} */ -ZEND_API void zend_delete_variable(zend_execute_data *ex, HashTable *ht, const char *name, int name_len, ulong hash_value TSRMLS_DC) /* {{{ */ +ZEND_API void zend_delete_variable(zend_execute_data *ex, HashTable *ht, zend_string *name TSRMLS_DC) /* {{{ */ { - if (zend_hash_quick_del(ht, name, name_len, hash_value) == SUCCESS) { - name_len--; + if (zend_hash_del(ht, name) == SUCCESS) { while (ex && ex->symbol_table == ht) { int i; if (ex->op_array) { for (i = 0; i < ex->op_array->last_var; i++) { - if (ex->op_array->vars[i].hash_value == hash_value && - ex->op_array->vars[i].name_len == name_len && - !memcmp(ex->op_array->vars[i].name, name, name_len)) { - *EX_CV_NUM(ex, i) = NULL; + if (ex->op_array->vars[i]->h == name->h && + ex->op_array->vars[i]->len == name->len && + !memcmp(ex->op_array->vars[i]->val, name->val, name->len)) { + ZVAL_NULL(EX_VAR_NUM_2(ex, i)); break; } } @@ -1718,37 +1669,31 @@ ZEND_API void zend_delete_variable(zend_execute_data *ex, HashTable *ht, const c } /* }}} */ -ZEND_API int zend_delete_global_variable_ex(const char *name, int name_len, ulong hash_value TSRMLS_DC) /* {{{ */ +ZEND_API int zend_delete_global_variable(zend_string *name TSRMLS_DC) /* {{{ */ { zend_execute_data *ex; - if (zend_hash_quick_exists(&EG(symbol_table), name, name_len + 1, hash_value)) { + if (zend_hash_del(&EG(symbol_table).ht, name) == SUCCESS) { for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) { - if (ex->op_array && ex->symbol_table == &EG(symbol_table)) { + if (ex->op_array && ex->symbol_table == &EG(symbol_table).ht) { int i; for (i = 0; i < ex->op_array->last_var; i++) { - if (ex->op_array->vars[i].hash_value == hash_value && - ex->op_array->vars[i].name_len == name_len && - !memcmp(ex->op_array->vars[i].name, name, name_len) + if (ex->op_array->vars[i]->h == name->h && + ex->op_array->vars[i]->len == name->len && + !memcmp(ex->op_array->vars[i]->val, name->val, name->len) ) { - *EX_CV_NUM(ex, i) = NULL; + ZVAL_UNDEF(EX_VAR_NUM_2(ex, i)); break; } } } } - return zend_hash_quick_del(&EG(symbol_table), name, name_len + 1, hash_value); + return SUCCESS; } return FAILURE; } /* }}} */ -ZEND_API int zend_delete_global_variable(const char *name, int name_len TSRMLS_DC) /* {{{ */ -{ - return zend_delete_global_variable_ex(name, name_len, zend_inline_hash_func(name, name_len + 1) TSRMLS_CC); -} -/* }}} */ - ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ { zend_uint i; @@ -1778,20 +1723,16 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ ex->symbol_table = EG(active_symbol_table); if (ex->op_array->this_var != -1 && - !*EX_CV_NUM(ex, ex->op_array->this_var) && - EG(This)) { - *EX_CV_NUM(ex, ex->op_array->this_var) = (zval**)EX_CV_NUM(ex, ex->op_array->last_var + ex->op_array->this_var); - **EX_CV_NUM(ex, ex->op_array->this_var) = EG(This); + Z_TYPE_P(EX_VAR_NUM_2(ex, ex->op_array->this_var)) == IS_UNDEF && + Z_TYPE(EG(This)) != IS_UNDEF) { + ZVAL_COPY_VALUE(EX_VAR_NUM_2(ex, ex->op_array->this_var), &EG(This)); } for (i = 0; i < ex->op_array->last_var; i++) { - if (*EX_CV_NUM(ex, i)) { - zend_hash_quick_update(EG(active_symbol_table), - ex->op_array->vars[i].name, - ex->op_array->vars[i].name_len + 1, - ex->op_array->vars[i].hash_value, - (void**)*EX_CV_NUM(ex, i), - sizeof(zval*), - (void**)EX_CV_NUM(ex, i)); + if (Z_TYPE_P(EX_VAR_NUM_2(ex, i)) != IS_UNDEF) { + // TODO: use INDIRECT??? + zend_hash_update(EG(active_symbol_table), + ex->op_array->vars[i], + EX_VAR_NUM_2(ex, i)); } } } -- cgit v1.2.1 From 4e66abad54b25ca367fcb6da78524e3c4024e2a0 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 12 Feb 2014 14:29:51 +0400 Subject: Use better data structures (incomplete) - refactored return_value handling --- Zend/zend_execute_API.c | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index c2be5c90c3..df91e5f0fa 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -138,7 +138,6 @@ void init_executor(TSRMLS_D) /* {{{ */ #if 0&&ZEND_DEBUG original_sigsegv_handler = signal(SIGSEGV, zend_handle_sigsegv); #endif -//??? EG(return_value_ptr_ptr) = NULL; EG(symtable_cache_ptr) = EG(symtable_cache) - 1; EG(symtable_cache_limit) = EG(symtable_cache) + SYMTABLE_CACHE_SIZE - 1; @@ -722,7 +721,6 @@ int call_user_function_ex(HashTable *function_table, zval *object, zval *functio int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TSRMLS_DC) /* {{{ */ { zend_uint i; -//??? zval **original_return_value; HashTable *calling_symbol_table; zend_op_array *original_op_array; zend_op **original_opline_ptr; @@ -912,16 +910,14 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EG(active_symbol_table) = NULL; } -//??? original_return_value = EG(return_value_ptr_ptr); original_op_array = EG(active_op_array); -//??? EG(return_value_ptr_ptr) = fci->retval_ptr_ptr; EG(active_op_array) = (zend_op_array *) EX(function_state).function; original_opline_ptr = EG(opline_ptr); if (EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) { -//??? *fci->retval_ptr_ptr = zend_generator_create_zval(EG(active_op_array) TSRMLS_CC); + zend_generator_create_zval(EG(active_op_array), fci->retval TSRMLS_CC); } else { - zend_execute(EG(active_op_array) TSRMLS_CC); + zend_execute(EG(active_op_array), fci->retval TSRMLS_CC); } if (!fci->symbol_table && EG(active_symbol_table)) { @@ -929,7 +925,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } EG(active_symbol_table) = calling_symbol_table; EG(active_op_array) = original_op_array; -//??? EG(return_value_ptr_ptr)=original_return_value; EG(opline_ptr) = original_opline_ptr; } else if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { int call_via_handler = (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0; @@ -1135,12 +1130,10 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s CG(compiler_options) = original_compiler_options; if (new_op_array) { -//??? zval *local_retval_ptr=NULL; -//??? zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr); + zval local_retval; zend_op **original_opline_ptr = EG(opline_ptr); int orig_interactive = CG(interactive); -//??? EG(return_value_ptr_ptr) = &local_retval_ptr; EG(active_op_array) = new_op_array; EG(no_extensions)=1; if (!EG(active_symbol_table)) { @@ -1149,7 +1142,8 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s CG(interactive) = 0; zend_try { - zend_execute(new_op_array TSRMLS_CC); + ZVAL_UNDEF(&local_retval); + zend_execute(new_op_array, &local_retval TSRMLS_CC); } zend_catch { destroy_op_array(new_op_array TSRMLS_CC); efree(new_op_array); @@ -1157,24 +1151,23 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s } zend_end_try(); CG(interactive) = orig_interactive; -//??? if (local_retval_ptr) { -//??? if (retval_ptr) { -//??? COPY_PZVAL_TO_ZVAL(*retval_ptr, local_retval_ptr); -//??? } else { -//??? zval_ptr_dtor(&local_retval_ptr); -//??? } -//??? } else { -//??? if (retval_ptr) { -//??? INIT_ZVAL(*retval_ptr); -//??? } -//??? } + if (Z_TYPE(local_retval) != IS_UNDEF) { + if (retval_ptr) { + COPY_PZVAL_TO_ZVAL(*retval_ptr, &local_retval); + } else { + zval_ptr_dtor(&local_retval); + } + } else { + if (retval_ptr) { + ZVAL_NULL(retval_ptr); + } + } EG(no_extensions)=0; EG(opline_ptr) = original_opline_ptr; EG(active_op_array) = original_active_op_array; destroy_op_array(new_op_array TSRMLS_CC); efree(new_op_array); -//??? EG(return_value_ptr_ptr) = original_return_value_ptr_ptr; retval = SUCCESS; } else { retval = FAILURE; @@ -1268,11 +1261,10 @@ void execute_new_code(TSRMLS_D) /* {{{ */ zend_release_labels(1 TSRMLS_CC); -//??? EG(return_value_ptr_ptr) = NULL; EG(active_op_array) = CG(active_op_array); orig_interactive = CG(interactive); CG(interactive) = 0; - zend_execute(CG(active_op_array) TSRMLS_CC); + zend_execute(CG(active_op_array), NULL TSRMLS_CC); CG(interactive) = orig_interactive; if (EG(exception)) { -- cgit v1.2.1 From be82a077769641331ee5914c60df44ba3f862aff Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 12 Feb 2014 18:08:11 +0400 Subject: Use better data structures (incomplete) --- Zend/zend_execute_API.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index df91e5f0fa..4894250827 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -797,10 +797,11 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS called_scope = fci_cache->called_scope; fci->object_ptr = fci_cache->object_ptr; ZVAL_COPY_VALUE(&EX(object), fci->object_ptr); -//??? if (fci->object_ptr && Z_TYPE_P(fci->object_ptr) == IS_OBJECT && -//??? (!EG(objects_store).object_buckets || !EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(fci->object_ptr)].valid)) { -//??? return FAILURE; -//??? } + if (fci->object_ptr && Z_TYPE_P(fci->object_ptr) == IS_OBJECT && + (!EG(objects_store).object_buckets || + !IS_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(fci->object_ptr)]))) { + return FAILURE; + } if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) { if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) { -- cgit v1.2.1 From 686a078258ec13b0e2d0a9ff581f07bef0ae2662 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 14 Feb 2014 14:55:48 +0400 Subject: Use better data structures (incomplete) --- Zend/zend_execute_API.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 4894250827..0e95e8f8f5 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -42,8 +42,8 @@ ZEND_API void (*zend_execute_ex)(zend_execute_data *execute_data TSRMLS_DC); ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC); /* true globals */ -//???ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, NULL, NULL, NULL, 0, NULL, NULL, 0 }; -//???ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, NULL }; +ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, {{0},0}, NULL, NULL, 0, NULL, NULL, 0 }; +ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, NULL }; #ifdef ZEND_WIN32 #include -- cgit v1.2.1 From 17bf59f895b886a3cc279ac91873588129d1a374 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 14 Feb 2014 17:48:45 +0400 Subject: Use better data structures (incomplete) --- Zend/zend_execute_API.c | 72 +++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 41 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 0e95e8f8f5..7176c1f147 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -429,11 +429,13 @@ ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ * Z_DELREF_P(zval_ptr); if (Z_REFCOUNT_P(zval_ptr) == 0) { zval_internal_dtor(zval_ptr); - } else if (Z_REFCOUNT_P(zval_ptr) == 1) { + } else if (Z_REFCOUNT_P(zval_ptr) == 1) { //??? Z_UNSET_ISREF_P(zval_ptr); - zend_reference *ref = Z_REF_P(zval_ptr); - ZVAL_COPY_VALUE(zval_ptr, Z_REFVAL_P(zval_ptr)); - efree(ref); + if (Z_ISREF_P(zval_ptr)) { + zend_reference *ref = Z_REF_P(zval_ptr); + ZVAL_COPY_VALUE(zval_ptr, Z_REFVAL_P(zval_ptr)); + efree(ref); + } } } /* }}} */ @@ -472,7 +474,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope zend_error(E_ERROR, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p)); } else if ((Z_TYPE_P(p) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { int refcount; -//??? zend_uchar is_ref; + zend_uchar is_ref; SEPARATE_ZVAL_IF_NOT_REF(p); @@ -485,17 +487,21 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope char *actual = Z_STRVAL_P(p); if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) { + int len; + zend_error(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(p)); - Z_STRLEN_P(p) -= ((colon - Z_STRVAL_P(p)) + 1); -//??? if (inline_change) { - zend_string *tmp = STR_INIT(colon, Z_STRLEN_P(p), 0); + len = Z_STRLEN_P(p) - ((colon - Z_STRVAL_P(p)) + 1); + if (inline_change) { + zend_string *tmp = STR_INIT(colon + 1, len, 0); STR_RELEASE(Z_STR_P(p)); Z_STR_P(p) = tmp; -//??? } else { + } else { //??? Z_STRVAL_P(p) = colon + 1; -//??? } + Z_STR_P(p) = STR_INIT(colon + 1, len, 0); + } } else { - char *save = actual, *slash; + zend_string *save = Z_STR_P(p); + char *slash; int actual_len = Z_STRLEN_P(p); if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) && (slash = (char *)zend_memrchr(actual, '\\', actual_len))) { actual = slash + 1; @@ -516,23 +522,19 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope --actual_len; } if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) { - int fix_save = 0; - if (save[0] == '\\') { - save++; - fix_save = 1; + if (save->val[0] == '\\') { + zend_error(E_ERROR, "Undefined constant '%s'", save->val + 1); + } else { + zend_error(E_ERROR, "Undefined constant '%s'", save->val); } - zend_error(E_ERROR, "Undefined constant '%s'", save); - if (fix_save) { - save--; + if (inline_change) { + STR_RELEASE(save); } -//??? if (inline_change) { -//??? str_efree(save); -//??? } save = NULL; } -//??? if (inline_change && save && save != actual) { -//??? str_efree(save); -//??? } + if (inline_change && save && save->val != actual) { + STR_RELEASE(save); + } zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); p->type = IS_STRING; if (!inline_change) { @@ -540,9 +542,9 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope } } } else { -//??? if (inline_change) { -//??? str_efree(Z_STRVAL_P(p)); -//??? } + if (inline_change) { + STR_RELEASE(Z_STR_P(p)); + } *p = const_value; } @@ -608,7 +610,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope } zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str_index, str_index); } - ZVAL_STRINGL(&const_value, str_index, str_index_len-3, 1); + ZVAL_STRINGL(&const_value, str_index, str_index_len-3); } #endif @@ -881,19 +883,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS if ((EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)) { ZVAL_UNDEF(&EG(This)); } else { - ZVAL_COPY_VALUE(&EG(This), fci->object_ptr); - - if (!Z_ISREF(EG(This))) { - Z_ADDREF(EG(This)); /* For $this pointer */ - } else { -//??? zval *this_ptr; -//??? -//??? ALLOC_ZVAL(this_ptr); -//??? *this_ptr = *EG(This); -//??? INIT_PZVAL(this_ptr); -//??? zval_copy_ctor(this_ptr); -//??? EG(This) = this_ptr; - } + ZVAL_COPY(&EG(This), fci->object_ptr); } } else { ZVAL_UNDEF(&EG(This)); -- cgit v1.2.1 From 2b9b9afa7a9a66f9c80013ce4121183bdff434e8 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 17 Feb 2014 17:59:18 +0400 Subject: Use better data structures (incomplete) --- Zend/zend_execute_API.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 7176c1f147..32a2a7545a 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -152,7 +152,7 @@ void init_executor(TSRMLS_D) /* {{{ */ EG(error_handling) = EH_NORMAL; zend_vm_stack_init(TSRMLS_C); - zend_vm_stack_push((void *) NULL TSRMLS_CC); +//??? zend_vm_stack_push((void *) NULL TSRMLS_CC); zend_hash_init(&EG(symbol_table).ht, 50, NULL, ZVAL_PTR_DTOR, 0); EG(active_symbol_table) = &EG(symbol_table).ht; @@ -426,15 +426,16 @@ ZEND_API void _zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ */ ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ */ { - Z_DELREF_P(zval_ptr); - if (Z_REFCOUNT_P(zval_ptr) == 0) { - zval_internal_dtor(zval_ptr); - } else if (Z_REFCOUNT_P(zval_ptr) == 1) { -//??? Z_UNSET_ISREF_P(zval_ptr); - if (Z_ISREF_P(zval_ptr)) { - zend_reference *ref = Z_REF_P(zval_ptr); - ZVAL_COPY_VALUE(zval_ptr, Z_REFVAL_P(zval_ptr)); - efree(ref); + if (IS_REFCOUNTED(Z_TYPE_P(zval_ptr))) { + Z_DELREF_P(zval_ptr); + if (Z_REFCOUNT_P(zval_ptr) == 0) { + _zval_internal_dtor_for_ptr(zval_ptr ZEND_FILE_LINE_CC); + } else if (Z_REFCOUNT_P(zval_ptr) == 1) { + if (Z_ISREF_P(zval_ptr)) { + zend_reference *ref = Z_REF_P(zval_ptr); + ZVAL_COPY_VALUE(zval_ptr, Z_REFVAL_P(zval_ptr)); + efree(ref); + } } } } @@ -563,7 +564,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope HashTable *ht = Z_ARRVAL_P(p); ZVAL_NEW_ARR(p); zend_hash_init(Z_ARRVAL_P(p), zend_hash_num_elements(ht), NULL, ZVAL_PTR_DTOR, 0); - zend_hash_copy(Z_ARRVAL_P(p), ht, (copy_ctor_func_t) zval_deep_copy); + zend_hash_copy(Z_ARRVAL_P(p), ht, zval_deep_copy); } /* First go over the array and see if there are any constant indices */ -- cgit v1.2.1 From a0fe8e5a91024710372625555b7d84dc9726e2da Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 18 Feb 2014 01:41:23 +0400 Subject: Use better data structures (incomplete) --- Zend/zend_execute_API.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 32a2a7545a..79d946d145 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -129,6 +129,7 @@ static int clean_non_persistent_class_full(zend_class_entry **ce TSRMLS_DC) /* { void init_executor(TSRMLS_D) /* {{{ */ { + zval tmp; zend_init_fpu(TSRMLS_C); ZVAL_NULL(&EG(uninitialized_zval)); @@ -152,7 +153,8 @@ void init_executor(TSRMLS_D) /* {{{ */ EG(error_handling) = EH_NORMAL; zend_vm_stack_init(TSRMLS_C); -//??? zend_vm_stack_push((void *) NULL TSRMLS_CC); + ZVAL_LONG(&tmp, 0); + zend_vm_stack_push(&tmp TSRMLS_CC); zend_hash_init(&EG(symbol_table).ht, 50, NULL, ZVAL_PTR_DTOR, 0); EG(active_symbol_table) = &EG(symbol_table).ht; @@ -734,6 +736,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zval current_this; zend_execute_data execute_data; zend_fcall_info_cache fci_cache_local; + zval tmp; fci->retval = NULL; @@ -821,7 +824,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS ZEND_VM_STACK_GROW_IF_NEEDED(fci->param_count + 1); for (i=0; iparam_count; i++) { - zval *param, tmp; + zval *param; if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)) { if (!Z_ISREF(fci->params[i]) && Z_REFCOUNT(fci->params[i]) > 1) { @@ -831,7 +834,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS !ARG_MAY_BE_SENT_BY_REF(EX(function_state).function, i + 1)) { if (i || UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (EG(argument_stack)->top))) { /* hack to clean up the stack */ - zend_vm_stack_push((void *) (zend_uintptr_t)i TSRMLS_CC); + ZVAL_LONG(&tmp, i); + zend_vm_stack_push(&tmp TSRMLS_CC); zend_vm_stack_clear_multiple(0 TSRMLS_CC); } @@ -866,7 +870,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } EX(function_state).arguments = zend_vm_stack_top(TSRMLS_C); - zend_vm_stack_push((void*)(zend_uintptr_t)fci->param_count TSRMLS_CC); + ZVAL_LONG(&tmp, fci->param_count); + zend_vm_stack_push(&tmp TSRMLS_CC); current_scope = EG(scope); EG(scope) = calling_scope; -- cgit v1.2.1 From 5de7115679522dec2f4725104c6f8c6e4a7bd8e4 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 18 Feb 2014 16:27:38 +0400 Subject: Use better data structures (incomplete; able to run bench.php) --- Zend/zend_execute_API.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 79d946d145..509e6b8ed6 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -434,9 +434,9 @@ ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ * _zval_internal_dtor_for_ptr(zval_ptr ZEND_FILE_LINE_CC); } else if (Z_REFCOUNT_P(zval_ptr) == 1) { if (Z_ISREF_P(zval_ptr)) { - zend_reference *ref = Z_REF_P(zval_ptr); - ZVAL_COPY_VALUE(zval_ptr, Z_REFVAL_P(zval_ptr)); - efree(ref); +//??? zend_reference *ref = Z_REF_P(zval_ptr); +//??? ZVAL_COPY_VALUE(zval_ptr, Z_REFVAL_P(zval_ptr)); +//??? efree(ref); } } } -- cgit v1.2.1 From 9e6c0c6a89e8b48042283fc42c9dc6f70cc41a44 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 18 Feb 2014 17:31:27 +0400 Subject: Use better data structures (incomplete) --- Zend/zend_execute_API.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 509e6b8ed6..21958308a0 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -738,7 +738,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_fcall_info_cache fci_cache_local; zval tmp; - fci->retval = NULL; + ZVAL_UNDEF(fci->retval); if (!EG(active)) { return FAILURE; /* executor is already inactive */ @@ -802,7 +802,11 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS calling_scope = fci_cache->calling_scope; called_scope = fci_cache->called_scope; fci->object_ptr = fci_cache->object_ptr; - ZVAL_COPY_VALUE(&EX(object), fci->object_ptr); + if (fci->object_ptr) { + ZVAL_COPY_VALUE(&EX(object), fci->object_ptr); + } else { + ZVAL_UNDEF(&EX(object)); + } if (fci->object_ptr && Z_TYPE_P(fci->object_ptr) == IS_OBJECT && (!EG(objects_store).object_buckets || !IS_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(fci->object_ptr)]))) { @@ -859,12 +863,9 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 ) { param = &tmp; ZVAL_DUP(param, &fci->params[i]); -//??? } else if (*fci->params[i] != &EG(uninitialized_zval)) { - Z_ADDREF(fci->params[i]); - param = &fci->params[i]; -//??? } else { -//??? param = &tmp; -//??? ZVAL_COPY_VALUE(param, &fci->params[i]); + } else { + param = &tmp; + ZVAL_COPY(param, &fci->params[i]); } zend_vm_stack_push(param TSRMLS_CC); } -- cgit v1.2.1 From 557994d50d6d712a2a23ba0bbb3169750bf0a0cf Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 19 Feb 2014 01:12:05 +0400 Subject: Use better data structures (incomplete) --- Zend/zend_execute_API.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 21958308a0..bf43338546 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1081,6 +1081,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zend_li EG(autoload_func) = fcall_cache.function_handler; zval_ptr_dtor(&args[0]); + zval_dtor(&fcall_info.function_name); zend_hash_del(EG(in_autoload), lc_name); @@ -1111,7 +1112,7 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s int retval; if (retval_ptr) { - ZVAL_STR(&pv, STR_ALLOC(str_len + sizeof("return ;"), 1)); + ZVAL_STR(&pv, STR_ALLOC(str_len + sizeof("return ;")-1, 1)); memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1); memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, str, str_len); Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';'; -- cgit v1.2.1 From 9067dbcd0d8d8bed6c723d274b162182f33281ea Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 19 Feb 2014 12:03:01 +0400 Subject: Use better data structures (incomplete) --- Zend/zend_execute_API.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index bf43338546..bbed28d783 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -511,7 +511,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope actual_len -= (actual - Z_STRVAL_P(p)); if (inline_change) { zend_string *s = STR_INIT(actual, actual_len, 0); - STR_RELEASE(Z_STR_P(p)); +//??? STR_RELEASE(Z_STR_P(p)); Z_STR_P(p) = s; } } @@ -531,12 +531,12 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope zend_error(E_ERROR, "Undefined constant '%s'", save->val); } if (inline_change) { - STR_RELEASE(save); +//??? STR_RELEASE(save); } save = NULL; } if (inline_change && save && save->val != actual) { - STR_RELEASE(save); +//??? STR_RELEASE(save); } zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); p->type = IS_STRING; @@ -546,12 +546,12 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope } } else { if (inline_change) { - STR_RELEASE(Z_STR_P(p)); +//??? STR_RELEASE(Z_STR_P(p)); } *p = const_value; } - Z_SET_REFCOUNT_P(p, refcount); + if (IS_REFCOUNTED(Z_TYPE_P(p))) Z_SET_REFCOUNT_P(p, refcount); //??? Z_SET_ISREF_TO_P(p, is_ref); } else if (Z_TYPE_P(p) == IS_CONSTANT_ARRAY) { zval *element, new_val; -- cgit v1.2.1 From 8bae1daa0c7f6b66283baedd5205906fc6357363 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 19 Feb 2014 14:35:28 +0400 Subject: Use better data structures (incomplete) --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index bbed28d783..dc194d051d 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1649,7 +1649,7 @@ ZEND_API void zend_delete_variable(zend_execute_data *ex, HashTable *ht, zend_st if (ex->op_array->vars[i]->h == name->h && ex->op_array->vars[i]->len == name->len && !memcmp(ex->op_array->vars[i]->val, name->val, name->len)) { - ZVAL_NULL(EX_VAR_NUM_2(ex, i)); + ZVAL_UNDEF(EX_VAR_NUM_2(ex, i)); break; } } -- cgit v1.2.1 From 76c28f878ae37975b5520aaedf4b8f2986fe540b Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Fri, 21 Feb 2014 22:39:27 +0800 Subject: Fixed missed REFCOUNTED checking --- Zend/zend_execute_API.c | 44 +++++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 21 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index dc194d051d..e0dede14f5 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -831,31 +831,33 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zval *param; if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)) { - if (!Z_ISREF(fci->params[i]) && Z_REFCOUNT(fci->params[i]) > 1) { - zval new_zval; - - if (fci->no_separation && - !ARG_MAY_BE_SENT_BY_REF(EX(function_state).function, i + 1)) { - if (i || UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (EG(argument_stack)->top))) { - /* hack to clean up the stack */ - ZVAL_LONG(&tmp, i); - zend_vm_stack_push(&tmp TSRMLS_CC); - zend_vm_stack_clear_multiple(0 TSRMLS_CC); + if (Z_REFCOUNTED(fci->params[i])) { + if (!Z_ISREF(fci->params[i]) && Z_REFCOUNT(fci->params[i]) > 1) { + zval new_zval; + + if (fci->no_separation && + !ARG_MAY_BE_SENT_BY_REF(EX(function_state).function, i + 1)) { + if (i || UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (EG(argument_stack)->top))) { + /* hack to clean up the stack */ + ZVAL_LONG(&tmp, i); + zend_vm_stack_push(&tmp TSRMLS_CC); + zend_vm_stack_clear_multiple(0 TSRMLS_CC); + } + + zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given", + i+1, + EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name->val : "", + EX(function_state).function->common.scope ? "::" : "", + EX(function_state).function->common.function_name->val); + return FAILURE; } - zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given", - i+1, - EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name->val : "", - EX(function_state).function->common.scope ? "::" : "", - EX(function_state).function->common.function_name->val); - return FAILURE; + ZVAL_DUP(&new_zval, &fci->params[i]); + Z_DELREF(fci->params[i]); + ZVAL_COPY_VALUE(&fci->params[i], &new_zval); } - - ZVAL_DUP(&new_zval, &fci->params[i]); - Z_DELREF(fci->params[i]); - ZVAL_COPY_VALUE(&fci->params[i], &new_zval); + Z_ADDREF(fci->params[i]); } - Z_ADDREF(fci->params[i]); //??? Z_SET_ISREF_PP(fci->params[i]); param = &fci->params[i]; } else if (Z_ISREF(fci->params[i]) && -- cgit v1.2.1 From 52bd62eca819e43e0fc6788c0ec4670ca4c8cddf Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 21 Feb 2014 20:35:40 +0400 Subject: Fixed assertions --- Zend/zend_execute_API.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index e0dede14f5..dd27e65656 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1582,8 +1582,10 @@ typedef struct _zend_abstract_info { int ctor; } zend_abstract_info; -static int zend_verify_abstract_class_function(zend_function *fn, zend_abstract_info *ai TSRMLS_DC) /* {{{ */ +static int zend_verify_abstract_class_function(zval *zv, zend_abstract_info *ai TSRMLS_DC) /* {{{ */ { + zend_function *fn = Z_PTR_P(zv); + if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) { if (ai->cnt < MAX_ABSTRACT_INFO_CNT) { ai->afn[ai->cnt] = fn; -- cgit v1.2.1 From 008a42e7c8799fa7885f805b714c16d8e703b35f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 21 Feb 2014 20:53:09 +0400 Subject: Fixed error messages --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index dd27e65656..147461f838 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -815,7 +815,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) { if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) { - zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EX(function_state).function->common.scope->name, EX(function_state).function->common.function_name); + zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EX(function_state).function->common.scope->name->val, EX(function_state).function->common.function_name->val); } if (EX(function_state).function->common.fn_flags & ZEND_ACC_DEPRECATED) { zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated", -- cgit v1.2.1 From 23c9d3eb01fd69af938b0b01e78f837e78993f51 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 24 Feb 2014 11:31:46 +0400 Subject: Fixed zend_rebuild_symbol_table() using IS_INDIRECT --- Zend/zend_execute_API.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 147461f838..26791c357b 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1724,10 +1724,10 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ } for (i = 0; i < ex->op_array->last_var; i++) { if (Z_TYPE_P(EX_VAR_NUM_2(ex, i)) != IS_UNDEF) { - // TODO: use INDIRECT??? - zend_hash_update(EG(active_symbol_table), + zval *zv = zend_hash_update(EG(active_symbol_table), ex->op_array->vars[i], EX_VAR_NUM_2(ex, i)); + ZVAL_INDIRECT(EX_VAR_NUM_2(ex, i), zv); } } } -- cgit v1.2.1 From 479b82c0d4c4c0cf3f3ccb4333ba9f2d8df65edd Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Mon, 24 Feb 2014 17:26:09 +0800 Subject: Fixed invalid write in vsprintf tests --- Zend/zend_execute_API.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 26791c357b..0bb4c6f0a3 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -251,14 +251,14 @@ void shutdown_executor(TSRMLS_D) /* {{{ */ * so that if handler used some class, crash would not happen */ if (Z_TYPE(EG(user_error_handler)) != IS_UNDEF) { zeh = &EG(user_error_handler); - ZVAL_UNDEF(&EG(user_error_handler)); zval_ptr_dtor(zeh); + ZVAL_UNDEF(&EG(user_error_handler)); } if (Z_TYPE(EG(user_exception_handler)) != IS_UNDEF) { zeh = &EG(user_exception_handler); - ZVAL_UNDEF(&EG(user_exception_handler)); zval_ptr_dtor(zeh); + ZVAL_UNDEF(&EG(user_exception_handler)); } zend_stack_destroy(&EG(user_error_handlers_error_reporting)); -- cgit v1.2.1 From f4c2810ab45293dea7b176069b73b33bb621fbb5 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 24 Feb 2014 15:25:24 +0400 Subject: fixed support for constant expressions --- Zend/zend_execute_API.c | 70 +++++++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 32 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 26791c357b..97c3932ac8 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -451,7 +451,7 @@ ZEND_API int zend_is_true(zval *op TSRMLS_DC) /* {{{ */ #include "../TSRM/tsrm_strtok_r.h" -#define IS_VISITED_CONSTANT IS_CONSTANT_INDEX +#define IS_VISITED_CONSTANT 0x080 //??? IS_CONSTANT_INDEX #define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT) #define Z_REAL_TYPE_P(p) (Z_TYPE_P(p) & ~IS_VISITED_CONSTANT) #define MARK_CONSTANT_VISITED(p) Z_TYPE_P(p) |= IS_VISITED_CONSTANT @@ -460,10 +460,10 @@ static void zval_deep_copy(zval *p) { zval value; - ZVAL_COPY_VALUE(&value, p); - Z_TYPE(value) &= ~IS_CONSTANT_INDEX; - zval_copy_ctor(&value); - Z_TYPE(value) = Z_TYPE_P(p); + ZVAL_DUP(&value, p); +//??? Z_TYPE(value) &= ~IS_CONSTANT_INDEX; +//??? zval_copy_ctor(&value); +//??? Z_TYPE(value) = Z_TYPE_P(p); ZVAL_COPY_VALUE(p, &value); } @@ -546,9 +546,9 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope } } else { if (inline_change) { -//??? STR_RELEASE(Z_STR_P(p)); + STR_RELEASE(Z_STR_P(p)); } - *p = const_value; + ZVAL_COPY_VALUE(p, &const_value); } if (IS_REFCOUNTED(Z_TYPE_P(p))) Z_SET_REFCOUNT_P(p, refcount); @@ -572,56 +572,62 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope /* First go over the array and see if there are any constant indices */ zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); while ((element = zend_hash_get_current_data(Z_ARRVAL_P(p))) != NULL) { - if (!(Z_TYPE_P(element) & IS_CONSTANT_INDEX)) { + if (zend_hash_get_current_key_ex(Z_ARRVAL_P(p), &str_index, &num_index, 0, NULL) != HASH_KEY_IS_STRING) { zend_hash_move_forward(Z_ARRVAL_P(p)); continue; } - Z_TYPE_P(element) &= ~IS_CONSTANT_INDEX; - if (zend_hash_get_current_key_ex(Z_ARRVAL_P(p), &str_index, &num_index, 0, NULL) != HASH_KEY_IS_STRING) { + if (!(str_index->gc.u.v.flags & (IS_STR_CONSTANT | IS_STR_AST))) { zend_hash_move_forward(Z_ARRVAL_P(p)); continue; } + + if (str_index->gc.u.v.flags & IS_STR_AST) { + zend_ast_evaluate(&const_value, (zend_ast *)str_index->val, scope TSRMLS_CC); + zend_ast_destroy((zend_ast *)str_index->val); //??? -#if 0 - if (str_index[str_index_len - 2] == IS_CONSTANT_AST) { - zend_ast_evaluate(&const_value, *(zend_ast **)str_index, scope TSRMLS_CC); - zend_ast_destroy(*(zend_ast **)str_index); - } else if (!zend_get_constant_ex(str_index, str_index_len - 3, &const_value, scope, str_index[str_index_len - 2] TSRMLS_CC)) { - char *actual; - const char *save = str_index; - if ((colon = (char*)zend_memrchr(str_index, ':', str_index_len - 3))) { - zend_error(E_ERROR, "Undefined class constant '%s'", str_index); - str_index_len -= ((colon - str_index) + 1); - str_index = colon; + } else if (!zend_get_constant_ex(str_index->val, str_index->len, &const_value, scope, 0 /*???str_index[str_index_len - 2]*/ TSRMLS_CC)) { + char *actual, *str; + const char *save = str_index->val; + int len; + + str = str_index->val; + len = str_index->len; + if ((colon = (char*)zend_memrchr(str, ':', len))) { + zend_error(E_ERROR, "Undefined class constant '%s'", str); + len -= ((colon - str) + 1); + str = colon; } else { - if (str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) { - if ((actual = (char *)zend_memrchr(str_index, '\\', str_index_len - 3))) { + if (str_index->gc.u.v.flags & IS_STR_CONSTANT_UNQUALIFIED) { + if ((actual = (char *)zend_memrchr(str, '\\', len))) { actual++; - str_index_len -= (actual - str_index); - str_index = actual; + len -= (actual - str); + str = actual; } } - if (str_index[0] == '\\') { - ++str_index; - --str_index_len; + if (str[0] == '\\') { + ++str; + --len; } if (save[0] == '\\') { ++save; } - if ((str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) == 0) { + if (str_index->gc.u.v.flags & IS_STR_CONSTANT_UNQUALIFIED) { zend_error(E_ERROR, "Undefined constant '%s'", save); } zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str_index, str_index); } - ZVAL_STRINGL(&const_value, str_index, str_index_len-3); + if (str == str_index->val && len == str_index->len) { + ZVAL_STR(&const_value, str_index); + } else { + ZVAL_STRINGL(&const_value, str, len); + } } -#endif if (Z_REFCOUNT_P(element) > 1) { ZVAL_DUP(&new_val, element); /* preserve this bit for inheritance */ - Z_TYPE_P(element) |= IS_CONSTANT_INDEX; +//??? Z_TYPE_P(element) |= IS_CONSTANT_INDEX; zval_ptr_dtor(element); ZVAL_COPY_VALUE(element, &new_val); } -- cgit v1.2.1 From 595fc4d901cbb69d2d4fe46508b7303ac62428b8 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 24 Feb 2014 15:49:15 +0400 Subject: More constant related fixes --- Zend/zend_execute_API.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 1a074434df..28938e59da 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -585,7 +585,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope zend_ast_evaluate(&const_value, (zend_ast *)str_index->val, scope TSRMLS_CC); zend_ast_destroy((zend_ast *)str_index->val); //??? - } else if (!zend_get_constant_ex(str_index->val, str_index->len, &const_value, scope, 0 /*???str_index[str_index_len - 2]*/ TSRMLS_CC)) { + } else if (!zend_get_constant_ex(str_index->val, str_index->len, &const_value, scope, str_index->gc.u.v.flags TSRMLS_CC)) { char *actual, *str; const char *save = str_index->val; int len; @@ -611,10 +611,10 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope if (save[0] == '\\') { ++save; } - if (str_index->gc.u.v.flags & IS_STR_CONSTANT_UNQUALIFIED) { + if (!(str_index->gc.u.v.flags & IS_STR_CONSTANT_UNQUALIFIED)) { zend_error(E_ERROR, "Undefined constant '%s'", save); } - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str_index, str_index); + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str, str); } if (str == str_index->val && len == str_index->len) { ZVAL_STR(&const_value, str_index); -- cgit v1.2.1 From 789eb6dfc3aa524bf66c49b0677857baea90388a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 24 Feb 2014 16:35:55 +0400 Subject: Fixed create_function() --- Zend/zend_execute_API.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 28938e59da..7fb89bc046 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1179,9 +1179,7 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s } else { retval = FAILURE; } - if (retval_ptr) { - zval_dtor(&pv); - } + zval_dtor(&pv); return retval; } /* }}} */ -- cgit v1.2.1 From 499b553c18f1e4e7c09c5f8a20ddc78b7ce70309 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Tue, 25 Feb 2014 18:14:22 +0800 Subject: Fixed NULL pointer dereference --- Zend/zend_execute_API.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 7fb89bc046..425a04756b 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -371,10 +371,10 @@ ZEND_API const char *get_active_function_name(TSRMLS_D) /* {{{ */ } switch (EG(current_execute_data)->function_state.function->type) { case ZEND_USER_FUNCTION: { - const char *function_name = ((zend_op_array *) EG(current_execute_data)->function_state.function)->function_name->val; + zend_string *function_name = ((zend_op_array *) EG(current_execute_data)->function_state.function)->function_name; if (function_name) { - return function_name; + return function_name->val; } else { return "main"; } -- cgit v1.2.1 From 639e4e1afac8c79d28e1a4c3df48fc060b35b68e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 25 Feb 2014 16:03:34 +0400 Subject: Changes zend_is_callable() to use zend_string* instead of char* --- Zend/zend_execute_API.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 425a04756b..794f3dc010 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -777,20 +777,20 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } if (!fci_cache || !fci_cache->initialized) { - char *callable_name; + zend_string *callable_name; char *error = NULL; if (!fci_cache) { fci_cache = &fci_cache_local; } - if (!zend_is_callable_ex(&fci->function_name, fci->object_ptr, IS_CALLABLE_CHECK_SILENT, &callable_name, NULL, fci_cache, &error TSRMLS_CC)) { + if (!zend_is_callable_ex(&fci->function_name, fci->object_ptr, IS_CALLABLE_CHECK_SILENT, &callable_name, fci_cache, &error TSRMLS_CC)) { if (error) { - zend_error(E_WARNING, "Invalid callback %s, %s", callable_name, error); + zend_error(E_WARNING, "Invalid callback %s, %s", callable_name->val, error); efree(error); } if (callable_name) { - efree(callable_name); + STR_RELEASE(callable_name); } return FAILURE; } else if (error) { @@ -801,7 +801,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_error(E_STRICT, "%s", error); efree(error); } - efree(callable_name); + STR_RELEASE(callable_name); } EX(function_state).function = fci_cache->function_handler; -- cgit v1.2.1 From 77abd35b784e38afea5d1cd6613ec40372162ba1 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 25 Feb 2014 16:20:42 +0400 Subject: Fixed memory leak --- Zend/zend_execute_API.c | 1 + 1 file changed, 1 insertion(+) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 794f3dc010..863130bf29 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -663,6 +663,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope zend_ast_evaluate(&const_value, Z_ASTVAL_P(p), scope TSRMLS_CC); if (inline_change) { zend_ast_destroy(Z_ASTVAL_P(p)); + efree(Z_AST_P(p)); } ZVAL_COPY_VALUE(p, &const_value); } -- cgit v1.2.1 From 78fc6b3570f4c0eb4ade4f02857eaadb049e10d9 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 26 Feb 2014 01:09:34 +0400 Subject: Fixed refcounting --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 863130bf29..c8679625c1 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -623,7 +623,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope } } - if (Z_REFCOUNT_P(element) > 1) { + if (Z_REFCOUNTED_P(element) && Z_REFCOUNT_P(element) > 1) { ZVAL_DUP(&new_val, element); /* preserve this bit for inheritance */ -- cgit v1.2.1 From 3696e038e5e52cb231b5f0004c53cafed04f90c7 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 27 Feb 2014 16:07:36 +0400 Subject: Various fixes related to read_property(), read_dimension() and iterators refactoring --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index c8679625c1..e81339b138 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -477,7 +477,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope zend_error(E_ERROR, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p)); } else if ((Z_TYPE_P(p) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { int refcount; - zend_uchar is_ref; +//??? zend_uchar is_ref; SEPARATE_ZVAL_IF_NOT_REF(p); -- cgit v1.2.1 From 3810b4ab4ad220d6c682879d79a7941cba62feae Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 27 Feb 2014 16:41:41 +0400 Subject: Fixed constant expressions in array indeces handling --- Zend/zend_execute_API.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index e81339b138..cf634b6be7 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -582,8 +582,11 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope } if (str_index->gc.u.v.flags & IS_STR_AST) { - zend_ast_evaluate(&const_value, (zend_ast *)str_index->val, scope TSRMLS_CC); - zend_ast_destroy((zend_ast *)str_index->val); + zend_ast_ref *ast = *(zend_ast_ref **)str_index->val; + + zend_ast_evaluate(&const_value, ast->ast, scope TSRMLS_CC); + zend_ast_destroy(ast->ast); + efree(ast); //??? } else if (!zend_get_constant_ex(str_index->val, str_index->len, &const_value, scope, str_index->gc.u.v.flags TSRMLS_CC)) { char *actual, *str; -- cgit v1.2.1 From 19670c2bbcd5fc1339e160929cc81db3ae940392 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 5 Mar 2014 01:54:21 +0400 Subject: Fixied calling object closures from internal functions --- Zend/zend_execute_API.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index cf634b6be7..c89240fd6a 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -43,7 +43,7 @@ ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, zend /* true globals */ ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, {{0},0}, NULL, NULL, 0, NULL, NULL, 0 }; -ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, NULL }; +ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, {{0},0} }; #ifdef ZEND_WIN32 #include @@ -811,12 +811,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EX(function_state).function = fci_cache->function_handler; calling_scope = fci_cache->calling_scope; called_scope = fci_cache->called_scope; - fci->object_ptr = fci_cache->object_ptr; - if (fci->object_ptr) { - ZVAL_COPY_VALUE(&EX(object), fci->object_ptr); - } else { - ZVAL_UNDEF(&EX(object)); - } + fci->object_ptr = &fci_cache->object; + ZVAL_COPY_VALUE(&EX(object), fci->object_ptr); if (fci->object_ptr && Z_TYPE_P(fci->object_ptr) == IS_OBJECT && (!EG(objects_store).object_buckets || !IS_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(fci->object_ptr)]))) { @@ -1084,7 +1080,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zend_li fcall_cache.function_handler = EG(autoload_func); fcall_cache.calling_scope = NULL; fcall_cache.called_scope = NULL; - fcall_cache.object_ptr = NULL; + ZVAL_UNDEF(&fcall_cache.object); zend_exception_save(TSRMLS_C); retval = zend_call_function(&fcall_info, &fcall_cache TSRMLS_CC); -- cgit v1.2.1 From 37337373287544f39d696c2fb357a56e99e6cecc Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 5 Mar 2014 13:55:56 +0400 Subject: Handle interned strings as non-refcounted scalars --- Zend/zend_execute_API.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index c89240fd6a..3091b85416 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -428,7 +428,7 @@ ZEND_API void _zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ */ ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ */ { - if (IS_REFCOUNTED(Z_TYPE_P(zval_ptr))) { + if (Z_REFCOUNTED_P(zval_ptr)) { Z_DELREF_P(zval_ptr); if (Z_REFCOUNT_P(zval_ptr) == 0) { _zval_internal_dtor_for_ptr(zval_ptr ZEND_FILE_LINE_CC); @@ -551,7 +551,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope ZVAL_COPY_VALUE(p, &const_value); } - if (IS_REFCOUNTED(Z_TYPE_P(p))) Z_SET_REFCOUNT_P(p, refcount); + if (Z_REFCOUNTED_P(p)) Z_SET_REFCOUNT_P(p, refcount); //??? Z_SET_ISREF_TO_P(p, is_ref); } else if (Z_TYPE_P(p) == IS_CONSTANT_ARRAY) { zval *element, new_val; -- cgit v1.2.1 From 84c092f6d623a9e58963db84c507624a13b50e17 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 5 Mar 2014 16:17:00 +0400 Subject: Fixed by reference parameter passing from internal functions --- Zend/zend_execute_API.c | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 3091b85416..0d3637a937 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -837,34 +837,33 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zval *param; if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)) { - if (Z_REFCOUNTED(fci->params[i])) { - if (!Z_ISREF(fci->params[i]) && Z_REFCOUNT(fci->params[i]) > 1) { - zval new_zval; - - if (fci->no_separation && - !ARG_MAY_BE_SENT_BY_REF(EX(function_state).function, i + 1)) { - if (i || UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (EG(argument_stack)->top))) { - /* hack to clean up the stack */ - ZVAL_LONG(&tmp, i); - zend_vm_stack_push(&tmp TSRMLS_CC); - zend_vm_stack_clear_multiple(0 TSRMLS_CC); - } - - zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given", - i+1, - EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name->val : "", - EX(function_state).function->common.scope ? "::" : "", - EX(function_state).function->common.function_name->val); - return FAILURE; + if (!Z_REFCOUNTED(fci->params[i]) || + (!Z_ISREF(fci->params[i]) && Z_REFCOUNT(fci->params[i]) > 1)) { + + if (fci->no_separation && + !ARG_MAY_BE_SENT_BY_REF(EX(function_state).function, i + 1)) { + if (i || UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (EG(argument_stack)->top))) { + /* hack to clean up the stack */ + ZVAL_LONG(&tmp, i); + zend_vm_stack_push(&tmp TSRMLS_CC); + zend_vm_stack_clear_multiple(0 TSRMLS_CC); } - ZVAL_DUP(&new_zval, &fci->params[i]); - Z_DELREF(fci->params[i]); - ZVAL_COPY_VALUE(&fci->params[i], &new_zval); + zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given", + i+1, + EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name->val : "", + EX(function_state).function->common.scope ? "::" : "", + EX(function_state).function->common.function_name->val); + return FAILURE; } + + zval_copy_ctor(&fci->params[i]); + } else if (!Z_ISREF(fci->params[i])) { + ZVAL_NEW_REF(&fci->params[i], &fci->params[i]); + Z_ADDREF(fci->params[i]); + } else if (Z_REFCOUNTED(fci->params[i])) { Z_ADDREF(fci->params[i]); } -//??? Z_SET_ISREF_PP(fci->params[i]); param = &fci->params[i]; } else if (Z_ISREF(fci->params[i]) && /* don't separate references for __call */ -- cgit v1.2.1 From 018be97c0d324453e7505d62f4a39fd202089cce Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 6 Mar 2014 00:15:56 +0400 Subject: Fixed support for undefined constants in RECV_INIT --- Zend/zend_execute_API.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 0d3637a937..02030ff413 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -531,17 +531,16 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope zend_error(E_ERROR, "Undefined constant '%s'", save->val); } if (inline_change) { -//??? STR_RELEASE(save); + STR_RELEASE(save); } save = NULL; } - if (inline_change && save && save->val != actual) { -//??? STR_RELEASE(save); - } zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); p->type = IS_STRING; if (!inline_change) { ZVAL_STRINGL(p, actual, actual_len); + } else if (save) { + STR_RELEASE(save); } } } else { -- cgit v1.2.1 From f3b4b1688314caa6f3dc32ef6aa796642c408d1f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 6 Mar 2014 01:04:28 +0400 Subject: Fixed passing reference by value in call_user_func() --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 02030ff413..fb214dba10 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -868,7 +868,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS /* don't separate references for __call */ (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 ) { param = &tmp; - ZVAL_DUP(param, &fci->params[i]); + ZVAL_DUP(param, Z_REFVAL(fci->params[i])); } else { param = &tmp; ZVAL_COPY(param, &fci->params[i]); -- cgit v1.2.1 From 8d2fb9d479bf13381d67e400e3b8c7aa28d7a480 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 6 Mar 2014 13:32:43 +0400 Subject: Internal functions may return (e.g. on wrong arguments) keeping the original return_value. So we have to initialize return_value as IS_NULL. --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index fb214dba10..7ddb526421 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -932,7 +932,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EG(opline_ptr) = original_opline_ptr; } else if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { int call_via_handler = (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0; -//??? ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr); + ZVAL_NULL(fci->retval); if (EX(function_state).function->common.scope) { EG(scope) = EX(function_state).function->common.scope; } -- cgit v1.2.1 From 6b303a6bd6fe336ee96d99f3e8912fe86aa7cf1a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 7 Mar 2014 01:33:33 +0400 Subject: Fixed refcounting --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 7ddb526421..0b632b05e4 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -539,7 +539,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope p->type = IS_STRING; if (!inline_change) { ZVAL_STRINGL(p, actual, actual_len); - } else if (save) { + } else if (save && save->val != actual) { STR_RELEASE(save); } } -- cgit v1.2.1 From 4b40e40ad0cca02f629cb89f0912d8eff8def1f0 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sun, 9 Mar 2014 11:43:47 +0800 Subject: Fixed memleak while sending IS_REFERENCE --- Zend/zend_execute_API.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 0b632b05e4..8faba97fc7 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -858,8 +858,10 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zval_copy_ctor(&fci->params[i]); } else if (!Z_ISREF(fci->params[i])) { + if (Z_REFCOUNTED(fci->params[i])) { + Z_ADDREF(fci->params[i]); + } ZVAL_NEW_REF(&fci->params[i], &fci->params[i]); - Z_ADDREF(fci->params[i]); } else if (Z_REFCOUNTED(fci->params[i])) { Z_ADDREF(fci->params[i]); } -- cgit v1.2.1 From 4aeae157062f69deb36e16f13ff0ddff62fd487c Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Mon, 10 Mar 2014 11:29:28 +0800 Subject: An demo(for review) to show how to fix the problem we meet --- Zend/zend_execute_API.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 8faba97fc7..9721fbda7b 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1728,10 +1728,9 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ } for (i = 0; i < ex->op_array->last_var; i++) { if (Z_TYPE_P(EX_VAR_NUM_2(ex, i)) != IS_UNDEF) { - zval *zv = zend_hash_update(EG(active_symbol_table), - ex->op_array->vars[i], - EX_VAR_NUM_2(ex, i)); - ZVAL_INDIRECT(EX_VAR_NUM_2(ex, i), zv); + zval zv; + ZVAL_INDIRECT(&zv, EX_VAR_NUM_2(ex, i)); + zend_hash_update(EG(active_symbol_table), ex->op_array->vars[i], &zv); } } } -- cgit v1.2.1 From 80625f20e59a195966d721bb467ce8cbf54bf807 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Mon, 10 Mar 2014 16:24:35 +0800 Subject: Revert "An demo(for review) to show how to fix the problem we meet" This reverts commit 4aeae157062f69deb36e16f13ff0ddff62fd487c. --- Zend/zend_execute_API.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 9721fbda7b..8faba97fc7 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1728,9 +1728,10 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ } for (i = 0; i < ex->op_array->last_var; i++) { if (Z_TYPE_P(EX_VAR_NUM_2(ex, i)) != IS_UNDEF) { - zval zv; - ZVAL_INDIRECT(&zv, EX_VAR_NUM_2(ex, i)); - zend_hash_update(EG(active_symbol_table), ex->op_array->vars[i], &zv); + zval *zv = zend_hash_update(EG(active_symbol_table), + ex->op_array->vars[i], + EX_VAR_NUM_2(ex, i)); + ZVAL_INDIRECT(EX_VAR_NUM_2(ex, i), zv); } } } -- cgit v1.2.1 From 60c354510b6731ec8348af9c5e230a4859c7c383 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Mon, 10 Mar 2014 16:25:05 +0800 Subject: An demo(for review) to show how to fix the problem(symbol table resize) --- Zend/zend_execute_API.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 8faba97fc7..2d6cc38d92 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -156,7 +156,7 @@ void init_executor(TSRMLS_D) /* {{{ */ ZVAL_LONG(&tmp, 0); zend_vm_stack_push(&tmp TSRMLS_CC); - zend_hash_init(&EG(symbol_table).ht, 50, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_init(&EG(symbol_table).ht, 50, NULL, ZVAL_INDIRECT_PTR_DTOR, 0); EG(active_symbol_table) = &EG(symbol_table).ht; zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator TSRMLS_CC); @@ -426,6 +426,16 @@ ZEND_API void _zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ */ } /* }}} */ +ZEND_API void zval_indirect_ptr_dtor(zval *zval_ptr) /* {{{ */ +{ + if (Z_TYPE_P(zval_ptr) == IS_INDIRECT) { + zval_ptr = Z_INDIRECT_P(zval_ptr); + } + zval_ptr_dtor(zval_ptr); +} + +/* }}} */ + ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ */ { if (Z_REFCOUNTED_P(zval_ptr)) { @@ -1716,7 +1726,7 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ EG(active_symbol_table) = *(EG(symtable_cache_ptr)--); } else { ALLOC_HASHTABLE(EG(active_symbol_table)); - zend_hash_init(EG(active_symbol_table), ex->op_array->last_var, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_init(EG(active_symbol_table), ex->op_array->last_var, NULL, ZVAL_INDIRECT_PTR_DTOR, 0); /*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/ } ex->symbol_table = EG(active_symbol_table); @@ -1728,10 +1738,9 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ } for (i = 0; i < ex->op_array->last_var; i++) { if (Z_TYPE_P(EX_VAR_NUM_2(ex, i)) != IS_UNDEF) { - zval *zv = zend_hash_update(EG(active_symbol_table), - ex->op_array->vars[i], - EX_VAR_NUM_2(ex, i)); - ZVAL_INDIRECT(EX_VAR_NUM_2(ex, i), zv); + zval zv; + ZVAL_INDIRECT(&zv, EX_VAR_NUM_2(ex, i)); + zend_hash_update(EG(active_symbol_table), ex->op_array->vars[i], &zv); } } } -- cgit v1.2.1 From 53e312c66342c5bf307aff9fca939c749bdafe49 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Tue, 11 Mar 2014 14:23:14 +0800 Subject: Review ended Revert "An demo(for review) to show how to fix the problem(symbol table resize)" This reverts commit 60c354510b6731ec8348af9c5e230a4859c7c383. --- Zend/zend_execute_API.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 2d6cc38d92..8faba97fc7 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -156,7 +156,7 @@ void init_executor(TSRMLS_D) /* {{{ */ ZVAL_LONG(&tmp, 0); zend_vm_stack_push(&tmp TSRMLS_CC); - zend_hash_init(&EG(symbol_table).ht, 50, NULL, ZVAL_INDIRECT_PTR_DTOR, 0); + zend_hash_init(&EG(symbol_table).ht, 50, NULL, ZVAL_PTR_DTOR, 0); EG(active_symbol_table) = &EG(symbol_table).ht; zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator TSRMLS_CC); @@ -426,16 +426,6 @@ ZEND_API void _zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ */ } /* }}} */ -ZEND_API void zval_indirect_ptr_dtor(zval *zval_ptr) /* {{{ */ -{ - if (Z_TYPE_P(zval_ptr) == IS_INDIRECT) { - zval_ptr = Z_INDIRECT_P(zval_ptr); - } - zval_ptr_dtor(zval_ptr); -} - -/* }}} */ - ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ */ { if (Z_REFCOUNTED_P(zval_ptr)) { @@ -1726,7 +1716,7 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ EG(active_symbol_table) = *(EG(symtable_cache_ptr)--); } else { ALLOC_HASHTABLE(EG(active_symbol_table)); - zend_hash_init(EG(active_symbol_table), ex->op_array->last_var, NULL, ZVAL_INDIRECT_PTR_DTOR, 0); + zend_hash_init(EG(active_symbol_table), ex->op_array->last_var, NULL, ZVAL_PTR_DTOR, 0); /*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/ } ex->symbol_table = EG(active_symbol_table); @@ -1738,9 +1728,10 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ } for (i = 0; i < ex->op_array->last_var; i++) { if (Z_TYPE_P(EX_VAR_NUM_2(ex, i)) != IS_UNDEF) { - zval zv; - ZVAL_INDIRECT(&zv, EX_VAR_NUM_2(ex, i)); - zend_hash_update(EG(active_symbol_table), ex->op_array->vars[i], &zv); + zval *zv = zend_hash_update(EG(active_symbol_table), + ex->op_array->vars[i], + EX_VAR_NUM_2(ex, i)); + ZVAL_INDIRECT(EX_VAR_NUM_2(ex, i), zv); } } } -- cgit v1.2.1 From d708d3c596aa16afa9ca4906ea1fa6579b74b494 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 11 Mar 2014 22:33:28 +0400 Subject: Fixed passing arguments by reference from internal functions --- Zend/zend_execute_API.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 8faba97fc7..ea02c0f160 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -856,7 +856,12 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS return FAILURE; } - zval_copy_ctor(&fci->params[i]); + if (Z_REFCOUNTED(fci->params[i])) { + Z_DELREF(fci->params[i]); + } + ZVAL_DUP(&tmp, &fci->params[i]); + ZVAL_NEW_REF(&fci->params[i], &tmp); + Z_ADDREF(fci->params[i]); } else if (!Z_ISREF(fci->params[i])) { if (Z_REFCOUNTED(fci->params[i])) { Z_ADDREF(fci->params[i]); -- cgit v1.2.1 From aa5f55306b4bd630e9304e9a8d1ea10cf4121f78 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 17 Mar 2014 23:15:22 +0400 Subject: Refactored EG(active_symbol_table) to be zend_array* instead of HashTable* --- Zend/zend_execute_API.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index ea02c0f160..339a71b901 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -157,7 +157,7 @@ void init_executor(TSRMLS_D) /* {{{ */ zend_vm_stack_push(&tmp TSRMLS_CC); zend_hash_init(&EG(symbol_table).ht, 50, NULL, ZVAL_PTR_DTOR, 0); - EG(active_symbol_table) = &EG(symbol_table).ht; + EG(active_symbol_table) = &EG(symbol_table); zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator TSRMLS_CC); EG(opline_ptr) = NULL; @@ -302,8 +302,8 @@ void shutdown_executor(TSRMLS_D) /* {{{ */ } while (EG(symtable_cache_ptr)>=EG(symtable_cache)) { - zend_hash_destroy(*EG(symtable_cache_ptr)); - FREE_HASHTABLE(*EG(symtable_cache_ptr)); + zend_hash_destroy(&(*EG(symtable_cache_ptr))->ht); + efree(*EG(symtable_cache_ptr)); EG(symtable_cache_ptr)--; } } zend_end_try(); @@ -714,7 +714,7 @@ int call_user_function(HashTable *function_table, zval *object, zval *function_n } /* }}} */ -int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, zend_uint param_count, zval params[], int no_separation, HashTable *symbol_table TSRMLS_DC) /* {{{ */ +int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, zend_uint param_count, zval params[], int no_separation, zend_array *symbol_table TSRMLS_DC) /* {{{ */ { zend_fcall_info fci; @@ -735,7 +735,7 @@ int call_user_function_ex(HashTable *function_table, zval *object, zval *functio int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TSRMLS_DC) /* {{{ */ { zend_uint i; - HashTable *calling_symbol_table; + zend_array *calling_symbol_table; zend_op_array *original_op_array; zend_op **original_opline_ptr; zend_class_entry *current_scope; @@ -1636,7 +1636,7 @@ void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC) /* {{{ */ } /* }}} */ -ZEND_API void zend_reset_all_cv(HashTable *symbol_table TSRMLS_DC) /* {{{ */ +ZEND_API void zend_reset_all_cv(zend_array *symbol_table TSRMLS_DC) /* {{{ */ { zend_execute_data *ex; int i; @@ -1654,7 +1654,7 @@ ZEND_API void zend_reset_all_cv(HashTable *symbol_table TSRMLS_DC) /* {{{ */ ZEND_API void zend_delete_variable(zend_execute_data *ex, HashTable *ht, zend_string *name TSRMLS_DC) /* {{{ */ { if (zend_hash_del(ht, name) == SUCCESS) { - while (ex && ex->symbol_table == ht) { + while (ex && &ex->symbol_table->ht == ht) { int i; if (ex->op_array) { @@ -1679,7 +1679,7 @@ ZEND_API int zend_delete_global_variable(zend_string *name TSRMLS_DC) /* {{{ */ if (zend_hash_del(&EG(symbol_table).ht, name) == SUCCESS) { for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) { - if (ex->op_array && ex->symbol_table == &EG(symbol_table).ht) { + if (ex->op_array && ex->symbol_table == &EG(symbol_table)) { int i; for (i = 0; i < ex->op_array->last_var; i++) { if (ex->op_array->vars[i]->h == name->h && @@ -1720,8 +1720,10 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ /*printf("Cache hit! Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/ EG(active_symbol_table) = *(EG(symtable_cache_ptr)--); } else { - ALLOC_HASHTABLE(EG(active_symbol_table)); - zend_hash_init(EG(active_symbol_table), ex->op_array->last_var, NULL, ZVAL_PTR_DTOR, 0); + EG(active_symbol_table) = emalloc(sizeof(zend_array)); + EG(active_symbol_table)->gc.refcount = 0; + EG(active_symbol_table)->gc.u.v.type = IS_ARRAY; + zend_hash_init(&EG(active_symbol_table)->ht, ex->op_array->last_var, NULL, ZVAL_PTR_DTOR, 0); /*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/ } ex->symbol_table = EG(active_symbol_table); @@ -1733,7 +1735,7 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ } for (i = 0; i < ex->op_array->last_var; i++) { if (Z_TYPE_P(EX_VAR_NUM_2(ex, i)) != IS_UNDEF) { - zval *zv = zend_hash_update(EG(active_symbol_table), + zval *zv = zend_hash_update(&EG(active_symbol_table)->ht, ex->op_array->vars[i], EX_VAR_NUM_2(ex, i)); ZVAL_INDIRECT(EX_VAR_NUM_2(ex, i), zv); -- cgit v1.2.1 From da9a2872b0170d74ea1fce95af710bdb1242644c Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 18 Mar 2014 14:52:54 +0400 Subject: Fixed cleanup on request shutdown --- Zend/zend_execute_API.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 339a71b901..73c00eae03 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -103,27 +103,31 @@ static void zend_extension_deactivator(zend_extension *extension TSRMLS_DC) /* { } /* }}} */ -static int clean_non_persistent_function(zend_function *function TSRMLS_DC) /* {{{ */ +static int clean_non_persistent_function(zval *zv TSRMLS_DC) /* {{{ */ { + zend_function *function = Z_PTR_P(zv); return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE; } /* }}} */ -static int clean_non_persistent_function_full(zend_function *function TSRMLS_DC) /* {{{ */ +static int clean_non_persistent_function_full(zval *zv TSRMLS_DC) /* {{{ */ { + zend_function *function = Z_PTR_P(zv); return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE; } /* }}} */ -static int clean_non_persistent_class(zend_class_entry **ce TSRMLS_DC) /* {{{ */ +static int clean_non_persistent_class(zval *zv TSRMLS_DC) /* {{{ */ { - return ((*ce)->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE; + zend_class_entry *ce = Z_PTR_P(zv); + return (ce->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE; } /* }}} */ -static int clean_non_persistent_class_full(zend_class_entry **ce TSRMLS_DC) /* {{{ */ +static int clean_non_persistent_class_full(zval *zv TSRMLS_DC) /* {{{ */ { - return ((*ce)->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE; + zend_class_entry *ce = Z_PTR_P(zv); + return (ce->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE; } /* }}} */ -- cgit v1.2.1 From 36cd92a7d3ae83f8169c6d7cead06ecda0b53df3 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 20 Mar 2014 17:03:32 +0400 Subject: Fixed passing argument by refefence from internal functions --- Zend/zend_execute_API.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 73c00eae03..4ffa199d44 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -867,10 +867,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS ZVAL_NEW_REF(&fci->params[i], &tmp); Z_ADDREF(fci->params[i]); } else if (!Z_ISREF(fci->params[i])) { - if (Z_REFCOUNTED(fci->params[i])) { - Z_ADDREF(fci->params[i]); - } ZVAL_NEW_REF(&fci->params[i], &fci->params[i]); + Z_ADDREF(fci->params[i]); } else if (Z_REFCOUNTED(fci->params[i])) { Z_ADDREF(fci->params[i]); } -- cgit v1.2.1 From cce7d5a1eceed880e4d44bc19f644237dc5a3615 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 21 Mar 2014 00:34:26 +0400 Subject: Fixed refcounting --- Zend/zend_execute_API.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 4ffa199d44..b3dc41ac1a 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -640,6 +640,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope switch (Z_TYPE(const_value)) { case IS_STRING: + Z_ADDREF(const_value); ret = zend_symtable_update_current_key(Z_ARRVAL_P(p), Z_STR(const_value), HASH_UPDATE_KEY_IF_BEFORE); break; case IS_BOOL: @@ -659,7 +660,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope if (ret == SUCCESS) { zend_hash_move_forward(Z_ARRVAL_P(p)); } - zval_dtor(&const_value); + zval_ptr_dtor(&const_value); } zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC); zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); -- cgit v1.2.1 From 6123deb30fcd04e3f4c3e7d388705591e44142f9 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 21 Mar 2014 01:08:26 +0400 Subject: Fixed refcounting (proper fix) --- Zend/zend_execute_API.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index b3dc41ac1a..613f4a1e29 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -623,7 +623,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str, str); } if (str == str_index->val && len == str_index->len) { - ZVAL_STR(&const_value, str_index); + ZVAL_STR(&const_value, STR_COPY(str_index)); } else { ZVAL_STRINGL(&const_value, str, len); } @@ -640,7 +640,6 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope switch (Z_TYPE(const_value)) { case IS_STRING: - Z_ADDREF(const_value); ret = zend_symtable_update_current_key(Z_ARRVAL_P(p), Z_STR(const_value), HASH_UPDATE_KEY_IF_BEFORE); break; case IS_BOOL: @@ -660,7 +659,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope if (ret == SUCCESS) { zend_hash_move_forward(Z_ARRVAL_P(p)); } - zval_ptr_dtor(&const_value); + zval_dtor(&const_value); } zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC); zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); -- cgit v1.2.1 From ef6919e6f2ffc951b9014778f74e79c7a6fbe3eb Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 21 Mar 2014 13:51:18 +0400 Subject: Fixed static data cleanup --- Zend/zend_execute_API.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 613f4a1e29..a90dade139 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -282,11 +282,11 @@ void shutdown_executor(TSRMLS_D) /* {{{ */ * Note that only run-time accessed data need to be cleaned up, pre-defined data can * not contain objects and thus are not probelmatic */ if (EG(full_tables_cleanup)) { - zend_hash_apply(EG(function_table), (apply_func_t) zend_cleanup_function_data_full TSRMLS_CC); - zend_hash_apply(EG(class_table), (apply_func_t) zend_cleanup_class_data TSRMLS_CC); + zend_hash_apply(EG(function_table), zend_cleanup_function_data_full TSRMLS_CC); + zend_hash_apply(EG(class_table), zend_cleanup_class_data TSRMLS_CC); } else { - zend_hash_reverse_apply(EG(function_table), (apply_func_t) zend_cleanup_function_data TSRMLS_CC); - zend_hash_reverse_apply(EG(class_table), (apply_func_t) zend_cleanup_user_class_data TSRMLS_CC); + zend_hash_reverse_apply(EG(function_table), zend_cleanup_function_data TSRMLS_CC); + zend_hash_reverse_apply(EG(class_table), zend_cleanup_user_class_data TSRMLS_CC); zend_cleanup_internal_classes(TSRMLS_C); } } zend_end_try(); @@ -298,11 +298,11 @@ void shutdown_executor(TSRMLS_D) /* {{{ */ /* Destroy all op arrays */ if (EG(full_tables_cleanup)) { - zend_hash_reverse_apply(EG(function_table), (apply_func_t) clean_non_persistent_function_full TSRMLS_CC); - zend_hash_reverse_apply(EG(class_table), (apply_func_t) clean_non_persistent_class_full TSRMLS_CC); + zend_hash_reverse_apply(EG(function_table), clean_non_persistent_function_full TSRMLS_CC); + zend_hash_reverse_apply(EG(class_table), clean_non_persistent_class_full TSRMLS_CC); } else { - zend_hash_reverse_apply(EG(function_table), (apply_func_t) clean_non_persistent_function TSRMLS_CC); - zend_hash_reverse_apply(EG(class_table), (apply_func_t) clean_non_persistent_class TSRMLS_CC); + zend_hash_reverse_apply(EG(function_table), clean_non_persistent_function TSRMLS_CC); + zend_hash_reverse_apply(EG(class_table), clean_non_persistent_class TSRMLS_CC); } while (EG(symtable_cache_ptr)>=EG(symtable_cache)) { -- cgit v1.2.1 From 887189ca31eeac5f1f7dbcaf54405de0dc432f2d Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 26 Mar 2014 18:07:31 +0400 Subject: Refactored IS_INDIRECT usage for CV and object properties to support HashTable resizing --- Zend/zend_execute_API.c | 168 ++++++++++++++++++++++++++++++------------------ 1 file changed, 106 insertions(+), 62 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index a90dade139..0980517935 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -202,6 +202,9 @@ void init_executor(TSRMLS_D) /* {{{ */ static int zval_call_destructor(zval *zv TSRMLS_DC) /* {{{ */ { + if (Z_TYPE_P(zv) == IS_INDIRECT) { + zv = Z_INDIRECT_P(zv); + } if (Z_TYPE_P(zv) == IS_OBJECT && Z_REFCOUNT_P(zv) == 1) { return ZEND_HASH_APPLY_REMOVE; } else { @@ -210,8 +213,22 @@ static int zval_call_destructor(zval *zv TSRMLS_DC) /* {{{ */ } /* }}} */ +static int zend_unclean_zval_ptr_dtor(zval *zv) /* {{{ */ +{ + TSRMLS_FETCH(); + + if (Z_TYPE_P(zv) == IS_INDIRECT) { + zv = Z_INDIRECT_P(zv); + } + i_zval_ptr_dtor(zv ZEND_FILE_LINE_CC TSRMLS_CC); +} +/* }}} */ + void shutdown_destructors(TSRMLS_D) /* {{{ */ { + if (CG(unclean_shutdown)) { + EG(symbol_table).ht.pDestructor = zend_unclean_zval_ptr_dtor; + } zend_try { int symbols; do { @@ -246,6 +263,10 @@ void shutdown_executor(TSRMLS_D) /* {{{ */ } */ zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator TSRMLS_CC); + + if (CG(unclean_shutdown)) { + EG(symbol_table).ht.pDestructor = zend_unclean_zval_ptr_dtor; + } zend_hash_graceful_reverse_destroy(&EG(symbol_table).ht); } zend_end_try(); @@ -1638,65 +1659,9 @@ void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC) /* {{{ */ } /* }}} */ -ZEND_API void zend_reset_all_cv(zend_array *symbol_table TSRMLS_DC) /* {{{ */ -{ - zend_execute_data *ex; - int i; - - for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) { - if (ex->op_array && ex->symbol_table == symbol_table) { - for (i = 0; i < ex->op_array->last_var; i++) { - ZVAL_UNDEF(EX_VAR_NUM_2(ex, i)); - } - } - } -} -/* }}} */ - -ZEND_API void zend_delete_variable(zend_execute_data *ex, HashTable *ht, zend_string *name TSRMLS_DC) /* {{{ */ -{ - if (zend_hash_del(ht, name) == SUCCESS) { - while (ex && &ex->symbol_table->ht == ht) { - int i; - - if (ex->op_array) { - for (i = 0; i < ex->op_array->last_var; i++) { - if (ex->op_array->vars[i]->h == name->h && - ex->op_array->vars[i]->len == name->len && - !memcmp(ex->op_array->vars[i]->val, name->val, name->len)) { - ZVAL_UNDEF(EX_VAR_NUM_2(ex, i)); - break; - } - } - } - ex = ex->prev_execute_data; - } - } -} -/* }}} */ - ZEND_API int zend_delete_global_variable(zend_string *name TSRMLS_DC) /* {{{ */ { - zend_execute_data *ex; - - if (zend_hash_del(&EG(symbol_table).ht, name) == SUCCESS) { - for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) { - if (ex->op_array && ex->symbol_table == &EG(symbol_table)) { - int i; - for (i = 0; i < ex->op_array->last_var; i++) { - if (ex->op_array->vars[i]->h == name->h && - ex->op_array->vars[i]->len == name->len && - !memcmp(ex->op_array->vars[i]->val, name->val, name->len) - ) { - ZVAL_UNDEF(EX_VAR_NUM_2(ex, i)); - break; - } - } - } - } - return SUCCESS; - } - return FAILURE; + return zend_hash_del_ind(&EG(symbol_table).ht, name); } /* }}} */ @@ -1736,18 +1701,97 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ ZVAL_COPY_VALUE(EX_VAR_NUM_2(ex, ex->op_array->this_var), &EG(This)); } for (i = 0; i < ex->op_array->last_var; i++) { - if (Z_TYPE_P(EX_VAR_NUM_2(ex, i)) != IS_UNDEF) { - zval *zv = zend_hash_update(&EG(active_symbol_table)->ht, - ex->op_array->vars[i], - EX_VAR_NUM_2(ex, i)); - ZVAL_INDIRECT(EX_VAR_NUM_2(ex, i), zv); + zval zv; + + ZVAL_INDIRECT(&zv, EX_VAR_NUM_2(ex, i)); + zend_hash_update(&EG(active_symbol_table)->ht, + ex->op_array->vars[i], &zv); + } + } + } +} +/* }}} */ + +ZEND_API void zend_attach_symbol_table(TSRMLS_D) /* {{{ */ +{ + int i; + zend_execute_data *execute_data = EG(current_execute_data); + zend_op_array *op_array = execute_data->op_array; + HashTable *ht = &EG(active_symbol_table)->ht; + + /* copy real values from symbol table into CV slots and create + INDIRECT references to CV in symbol table */ + for (i = 0; i < op_array->last_var; i++) { + zval *zv = zend_hash_find(ht, op_array->vars[i]); + + if (zv) { + if (Z_TYPE_P(zv) == IS_INDIRECT) { + zval *val = Z_INDIRECT_P(zv); + if (Z_TYPE_P(val) == IS_UNDEF) { + ZVAL_UNDEF(EX_VAR_NUM(i)); + } else { + ZVAL_COPY_VALUE(EX_VAR_NUM(i), val); } + } else { + ZVAL_COPY_VALUE(EX_VAR_NUM(i), zv); } + } else { + ZVAL_UNDEF(EX_VAR_NUM(i)); + zv = zend_hash_update(ht, op_array->vars[i], EX_VAR_NUM(i)); } + ZVAL_INDIRECT(zv, EX_VAR_NUM(i)); } } /* }}} */ +ZEND_API void zend_detach_symbol_table(TSRMLS_D) /* {{{ */ +{ + int i; + zend_execute_data *execute_data = EG(current_execute_data); + zend_op_array *op_array = execute_data->op_array; + HashTable *ht = &EG(active_symbol_table)->ht; + + /* copy real values from CV slots into symbol table */ + for (i = 0; i < op_array->last_var; i++) { + zend_hash_update(ht, op_array->vars[i], EX_VAR_NUM(i)); + ZVAL_UNDEF(EX_VAR_NUM(i)); + } +} +/* }}} */ + +ZEND_API int zend_set_local_var(const char *name, int len, zval *value, int force TSRMLS_DC) /* {{{ */ +{ + if (!EG(active_symbol_table)) { + int i; + zend_execute_data *execute_data = EG(current_execute_data); + zend_op_array *op_array = execute_data->op_array; + zend_ulong h = zend_hash_func(name, len); + + if (op_array) { + for (i = 0; i < op_array->last_var; i++) { + if (op_array->vars[i]->h == h && + op_array->vars[i]->len == len && + memcmp(op_array->vars[i]->val, name, len) == 0) { + ZVAL_COPY_VALUE(EX_VAR_NUM(i), value); + return SUCCESS; + } + } + } + if (force) { + zend_rebuild_symbol_table(TSRMLS_C); + if (EG(active_symbol_table)) { + zend_hash_str_update(&EG(active_symbol_table)->ht, name, len, value); + } + } else { + return FAILURE; + } + } else { + return zend_hash_str_update_ind(&EG(active_symbol_table)->ht, name, len, value); + } + return SUCCESS; +} +/* }}} */ + /* * Local variables: * tab-width: 4 -- cgit v1.2.1 From f53c31265f411d9d8af5b745095aaf4507d046fe Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 27 Mar 2014 00:04:50 +0400 Subject: Fixed symbol table detaching --- Zend/zend_execute_API.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 0980517935..b3dfbf8e06 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1753,8 +1753,12 @@ ZEND_API void zend_detach_symbol_table(TSRMLS_D) /* {{{ */ /* copy real values from CV slots into symbol table */ for (i = 0; i < op_array->last_var; i++) { - zend_hash_update(ht, op_array->vars[i], EX_VAR_NUM(i)); - ZVAL_UNDEF(EX_VAR_NUM(i)); + if (Z_TYPE_P(EX_VAR_NUM(i)) == IS_UNDEF) { + zend_hash_del(ht, op_array->vars[i]); + } else { + zend_hash_update(ht, op_array->vars[i], EX_VAR_NUM(i)); + ZVAL_UNDEF(EX_VAR_NUM(i)); + } } } /* }}} */ -- cgit v1.2.1 From c6cba554544d9dc676d1cfa99447364c95768664 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 27 Mar 2014 13:39:09 +0400 Subject: Use ZVAL_DEREF() macro --- Zend/zend_execute_API.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index b3dfbf8e06..7e41512ad2 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -457,12 +457,12 @@ ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ * Z_DELREF_P(zval_ptr); if (Z_REFCOUNT_P(zval_ptr) == 0) { _zval_internal_dtor_for_ptr(zval_ptr ZEND_FILE_LINE_CC); - } else if (Z_REFCOUNT_P(zval_ptr) == 1) { - if (Z_ISREF_P(zval_ptr)) { +//??? } else if (Z_REFCOUNT_P(zval_ptr) == 1) { +//??? if (Z_ISREF_P(zval_ptr)) { //??? zend_reference *ref = Z_REF_P(zval_ptr); //??? ZVAL_COPY_VALUE(zval_ptr, Z_REFVAL_P(zval_ptr)); //??? efree(ref); - } +//??? } } } } -- cgit v1.2.1 From 9a8fbdf2f45b7f2c27a39c892117387046d45fd4 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 27 Mar 2014 16:00:25 +0400 Subject: Use CV variable offset instead of CV variable number --- Zend/zend_execute_API.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 7e41512ad2..c0b61b820b 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1696,9 +1696,9 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ ex->symbol_table = EG(active_symbol_table); if (ex->op_array->this_var != -1 && - Z_TYPE_P(EX_VAR_NUM_2(ex, ex->op_array->this_var)) == IS_UNDEF && + Z_TYPE_P(EX_VAR_2(ex, ex->op_array->this_var)) == IS_UNDEF && Z_TYPE(EG(This)) != IS_UNDEF) { - ZVAL_COPY_VALUE(EX_VAR_NUM_2(ex, ex->op_array->this_var), &EG(This)); + ZVAL_COPY_VALUE(EX_VAR_2(ex, ex->op_array->this_var), &EG(This)); } for (i = 0; i < ex->op_array->last_var; i++) { zval zv; -- cgit v1.2.1 From ea85451b65b904d0670c4011c819a15431720432 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 28 Mar 2014 02:11:22 +0400 Subject: Refactored data structures to keep zend_object* instead of a whole zval in some places --- Zend/zend_execute_API.c | 59 ++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 30 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index c0b61b820b..363f401230 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -39,11 +39,11 @@ #endif ZEND_API void (*zend_execute_ex)(zend_execute_data *execute_data TSRMLS_DC); -ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, zend_fcall_info *fci, int return_value_used TSRMLS_DC); +ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, zend_fcall_info *fci TSRMLS_DC); /* true globals */ ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, {{0},0}, NULL, NULL, 0, NULL, NULL, 0 }; -ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, {{0},0} }; +ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, NULL }; #ifdef ZEND_WIN32 #include @@ -191,7 +191,7 @@ void init_executor(TSRMLS_D) /* {{{ */ EG(scope) = NULL; EG(called_scope) = NULL; - ZVAL_UNDEF(&EG(This)); + ZVAL_OBJ(&EG(This), NULL); EG(active_op_array) = NULL; @@ -213,7 +213,7 @@ static int zval_call_destructor(zval *zv TSRMLS_DC) /* {{{ */ } /* }}} */ -static int zend_unclean_zval_ptr_dtor(zval *zv) /* {{{ */ +static void zend_unclean_zval_ptr_dtor(zval *zv) /* {{{ */ { TSRMLS_FETCH(); @@ -745,7 +745,7 @@ int call_user_function_ex(HashTable *function_table, zval *object, zval *functio fci.size = sizeof(fci); fci.function_table = function_table; - fci.object_ptr = object; + fci.object = object ? Z_OBJ_P(object) : NULL; ZVAL_COPY_VALUE(&fci.function_name, function_name); fci.retval = retval_ptr; fci.param_count = param_count; @@ -767,7 +767,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_class_entry *current_called_scope; zend_class_entry *calling_scope = NULL; zend_class_entry *called_scope = NULL; - zval current_this; + zend_object *current_this; zend_execute_data execute_data; zend_fcall_info_cache fci_cache_local; zval tmp; @@ -795,7 +795,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS execute_data = *EG(current_execute_data); EX(op_array) = NULL; EX(opline) = NULL; - ZVAL_UNDEF(&EX(object)); + EX(object) = NULL; } else { /* This only happens when we're called outside any execute()'s * It shouldn't be strictly necessary to NULL execute_data out, @@ -812,7 +812,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS fci_cache = &fci_cache_local; } - if (!zend_is_callable_ex(&fci->function_name, fci->object_ptr, IS_CALLABLE_CHECK_SILENT, &callable_name, fci_cache, &error TSRMLS_CC)) { + if (!zend_is_callable_ex(&fci->function_name, fci->object, IS_CALLABLE_CHECK_SILENT, &callable_name, fci_cache, &error TSRMLS_CC)) { if (error) { zend_error(E_WARNING, "Invalid callback %s, %s", callable_name->val, error); efree(error); @@ -835,11 +835,10 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EX(function_state).function = fci_cache->function_handler; calling_scope = fci_cache->calling_scope; called_scope = fci_cache->called_scope; - fci->object_ptr = &fci_cache->object; - ZVAL_COPY_VALUE(&EX(object), fci->object_ptr); - if (fci->object_ptr && Z_TYPE_P(fci->object_ptr) == IS_OBJECT && + EX(object) = fci->object = fci_cache->object; + if (fci->object && (!EG(objects_store).object_buckets || - !IS_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(fci->object_ptr)]))) { + !IS_VALID(EG(objects_store).object_buckets[fci->object->handle]))) { return FAILURE; } @@ -913,7 +912,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS current_scope = EG(scope); EG(scope) = calling_scope; - ZVAL_COPY_VALUE(¤t_this, &EG(This)); + current_this = Z_OBJ(EG(This)); current_called_scope = EG(called_scope); if (called_scope) { @@ -922,14 +921,12 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EG(called_scope) = NULL; } - if (fci->object_ptr) { - if ((EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)) { - ZVAL_UNDEF(&EG(This)); - } else { - ZVAL_COPY(&EG(This), fci->object_ptr); - } + if (!fci->object || + (EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)) { + Z_OBJ(EG(This)) = NULL; } else { - ZVAL_UNDEF(&EG(This)); + Z_OBJ(EG(This)) = fci->object; + Z_ADDREF(EG(This)); } EX(prev_execute_data) = EG(current_execute_data); @@ -968,9 +965,9 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } if (EXPECTED(zend_execute_internal == NULL)) { /* saves one function call if zend_execute_internal is not used */ - EX(function_state).function->internal_function.handler(fci->param_count, fci->retval, fci->object_ptr, 1 TSRMLS_CC); + EX(function_state).function->internal_function.handler(fci->param_count, fci->retval TSRMLS_CC); } else { - zend_execute_internal(&execute_data, fci, 1 TSRMLS_CC); + zend_execute_internal(&execute_data, fci TSRMLS_CC); } /* We shouldn't fix bad extensions here, because it can break proper ones (Bug #34045) @@ -991,8 +988,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS //??? ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr); /* Not sure what should be done here if it's a static method */ - if (fci->object_ptr) { - Z_OBJ_HT_P(fci->object_ptr)->call_method(EX(function_state).function->common.function_name, fci->param_count, fci->retval, fci->object_ptr, 1 TSRMLS_CC); + if (fci->object) { + fci->object->handlers->call_method(EX(function_state).function->common.function_name, fci->object, fci->param_count, fci->retval TSRMLS_CC); } else { zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object"); } @@ -1009,10 +1006,12 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } zend_vm_stack_clear_multiple(0 TSRMLS_CC); - zval_ptr_dtor(&EG(This)); + if (Z_OBJ(EG(This))) { + zval_ptr_dtor(&EG(This)); + } EG(called_scope) = current_called_scope; EG(scope) = current_scope; - ZVAL_COPY_VALUE(&EG(This), ¤t_this); + Z_OBJ(EG(This)) = current_this; EG(current_execute_data) = EX(prev_execute_data); if (EG(exception)) { @@ -1101,14 +1100,14 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zend_li fcall_info.retval = &local_retval; fcall_info.param_count = 1; fcall_info.params = args; - fcall_info.object_ptr = NULL; + fcall_info.object = NULL; fcall_info.no_separation = 1; fcall_cache.initialized = EG(autoload_func) ? 1 : 0; fcall_cache.function_handler = EG(autoload_func); fcall_cache.calling_scope = NULL; fcall_cache.called_scope = NULL; - ZVAL_UNDEF(&fcall_cache.object); + fcall_cache.object = NULL; zend_exception_save(TSRMLS_C); retval = zend_call_function(&fcall_info, &fcall_cache TSRMLS_CC); @@ -1697,7 +1696,7 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ if (ex->op_array->this_var != -1 && Z_TYPE_P(EX_VAR_2(ex, ex->op_array->this_var)) == IS_UNDEF && - Z_TYPE(EG(This)) != IS_UNDEF) { + Z_OBJ(EG(This))) { ZVAL_COPY_VALUE(EX_VAR_2(ex, ex->op_array->this_var), &EG(This)); } for (i = 0; i < ex->op_array->last_var; i++) { @@ -1790,7 +1789,7 @@ ZEND_API int zend_set_local_var(const char *name, int len, zval *value, int forc return FAILURE; } } else { - return zend_hash_str_update_ind(&EG(active_symbol_table)->ht, name, len, value); + return (zend_hash_str_update_ind(&EG(active_symbol_table)->ht, name, len, value) != NULL) ? SUCCESS : FAILURE; } return SUCCESS; } -- cgit v1.2.1 From 70b7950a75609c4386f996fe7cb1a005447262b4 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 1 Apr 2014 14:20:10 +0400 Subject: Exclude interned flags from constant flags --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 363f401230..7400840a49 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -612,7 +612,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope zend_ast_destroy(ast->ast); efree(ast); //??? - } else if (!zend_get_constant_ex(str_index->val, str_index->len, &const_value, scope, str_index->gc.u.v.flags TSRMLS_CC)) { + } else if (!zend_get_constant_ex(str_index->val, str_index->len, &const_value, scope, str_index->gc.u.v.flags & ~(IS_STR_PERSISTENT | IS_STR_INTERNED |IS_STR_PERMANENT) TSRMLS_CC)) { char *actual, *str; const char *save = str_index->val; int len; -- cgit v1.2.1 From 6b2ed577fd5c3eeee55be394d8faac50ab8602f9 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 1 Apr 2014 22:36:17 +0400 Subject: Avoid unnecessry reallocations --- Zend/zend_execute_API.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 7400840a49..d5f70a15c9 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1762,7 +1762,40 @@ ZEND_API void zend_detach_symbol_table(TSRMLS_D) /* {{{ */ } /* }}} */ -ZEND_API int zend_set_local_var(const char *name, int len, zval *value, int force TSRMLS_DC) /* {{{ */ +ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force TSRMLS_DC) /* {{{ */ +{ + if (!EG(active_symbol_table)) { + int i; + zend_execute_data *execute_data = EG(current_execute_data); + zend_op_array *op_array = execute_data->op_array; + zend_ulong h = STR_HASH_VAL(name); + + if (op_array) { + for (i = 0; i < op_array->last_var; i++) { + if (op_array->vars[i]->h == h && + op_array->vars[i]->len == name->len && + memcmp(op_array->vars[i]->val, name->val, name->len) == 0) { + ZVAL_COPY_VALUE(EX_VAR_NUM(i), value); + return SUCCESS; + } + } + } + if (force) { + zend_rebuild_symbol_table(TSRMLS_C); + if (EG(active_symbol_table)) { + zend_hash_update(&EG(active_symbol_table)->ht, name, value); + } + } else { + return FAILURE; + } + } else { + return (zend_hash_update_ind(&EG(active_symbol_table)->ht, name, value) != NULL) ? SUCCESS : FAILURE; + } + return SUCCESS; +} +/* }}} */ + +ZEND_API int zend_set_local_var_str(const char *name, int len, zval *value, int force TSRMLS_DC) /* {{{ */ { if (!EG(active_symbol_table)) { int i; -- cgit v1.2.1 From d8099d0468426dbee59f540048376653535270ce Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 2 Apr 2014 14:34:44 +0400 Subject: Changed data layout to allow more efficient operations --- Zend/zend_execute_API.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index d5f70a15c9..77ac0dc2cb 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -561,7 +561,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope save = NULL; } zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); - p->type = IS_STRING; + Z_TYPE_P(p) = IS_STRING; if (!inline_change) { ZVAL_STRINGL(p, actual, actual_len); } else if (save && save->val != actual) { @@ -600,19 +600,19 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope zend_hash_move_forward(Z_ARRVAL_P(p)); continue; } - if (!(str_index->gc.u.v.flags & (IS_STR_CONSTANT | IS_STR_AST))) { + if (!(GC_FLAGS(str_index) & (IS_STR_CONSTANT | IS_STR_AST))) { zend_hash_move_forward(Z_ARRVAL_P(p)); continue; } - if (str_index->gc.u.v.flags & IS_STR_AST) { + if (GC_FLAGS(str_index) & IS_STR_AST) { zend_ast_ref *ast = *(zend_ast_ref **)str_index->val; zend_ast_evaluate(&const_value, ast->ast, scope TSRMLS_CC); zend_ast_destroy(ast->ast); efree(ast); //??? - } else if (!zend_get_constant_ex(str_index->val, str_index->len, &const_value, scope, str_index->gc.u.v.flags & ~(IS_STR_PERSISTENT | IS_STR_INTERNED |IS_STR_PERMANENT) TSRMLS_CC)) { + } else if (!zend_get_constant_ex(str_index->val, str_index->len, &const_value, scope, GC_FLAGS(str_index) & ~(IS_STR_PERSISTENT | IS_STR_INTERNED |IS_STR_PERMANENT) TSRMLS_CC)) { char *actual, *str; const char *save = str_index->val; int len; @@ -624,7 +624,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope len -= ((colon - str) + 1); str = colon; } else { - if (str_index->gc.u.v.flags & IS_STR_CONSTANT_UNQUALIFIED) { + if (GC_FLAGS(str_index) & IS_STR_CONSTANT_UNQUALIFIED) { if ((actual = (char *)zend_memrchr(str, '\\', len))) { actual++; len -= (actual - str); @@ -638,7 +638,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope if (save[0] == '\\') { ++save; } - if (!(str_index->gc.u.v.flags & IS_STR_CONSTANT_UNQUALIFIED)) { + if (!(GC_FLAGS(str_index) & IS_STR_CONSTANT_UNQUALIFIED)) { zend_error(E_ERROR, "Undefined constant '%s'", save); } zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str, str); @@ -1687,8 +1687,8 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ EG(active_symbol_table) = *(EG(symtable_cache_ptr)--); } else { EG(active_symbol_table) = emalloc(sizeof(zend_array)); - EG(active_symbol_table)->gc.refcount = 0; - EG(active_symbol_table)->gc.u.v.type = IS_ARRAY; + GC_REFCOUNT(EG(active_symbol_table)) = 0; + GC_TYPE_INFO(EG(active_symbol_table)) = IS_ARRAY; zend_hash_init(&EG(active_symbol_table)->ht, ex->op_array->last_var, NULL, ZVAL_PTR_DTOR, 0); /*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/ } -- cgit v1.2.1 From 76cc99fe60d1e446a0250b4d778f02bcdbd7fc09 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 3 Apr 2014 15:26:23 +0400 Subject: Refactored ZVAL flags usage to simplify various checks (e.g. Z_REFCOUNTED(), candidate for GC, etc) --- Zend/zend_execute_API.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 77ac0dc2cb..a56b32a6f4 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -479,7 +479,7 @@ ZEND_API int zend_is_true(zval *op TSRMLS_DC) /* {{{ */ #define IS_VISITED_CONSTANT 0x080 //??? IS_CONSTANT_INDEX #define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT) #define Z_REAL_TYPE_P(p) (Z_TYPE_P(p) & ~IS_VISITED_CONSTANT) -#define MARK_CONSTANT_VISITED(p) Z_TYPE_P(p) |= IS_VISITED_CONSTANT +#define MARK_CONSTANT_VISITED(p) Z_TYPE_INFO_P(p) |= IS_VISITED_CONSTANT static void zval_deep_copy(zval *p) { @@ -500,7 +500,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope if (IS_CONSTANT_VISITED(p)) { zend_error(E_ERROR, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p)); - } else if ((Z_TYPE_P(p) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { + } else if (Z_TYPE_P(p) == IS_CONSTANT) { int refcount; //??? zend_uchar is_ref; @@ -508,10 +508,10 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope MARK_CONSTANT_VISITED(p); - refcount = Z_REFCOUNT_P(p); + refcount = Z_REFCOUNTED_P(p) ? Z_REFCOUNT_P(p) : 1; //??? is_ref = Z_ISREF_P(p); - if (!zend_get_constant_ex(Z_STRVAL_P(p), Z_STRLEN_P(p), &const_value, scope, Z_REAL_TYPE_P(p) TSRMLS_CC)) { + if (!zend_get_constant_ex(Z_STRVAL_P(p), Z_STRLEN_P(p), &const_value, scope, Z_CONST_FLAGS_P(p) TSRMLS_CC)) { char *actual = Z_STRVAL_P(p); if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) { @@ -527,17 +527,19 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope //??? Z_STRVAL_P(p) = colon + 1; Z_STR_P(p) = STR_INIT(colon + 1, len, 0); } + Z_TYPE_FLAGS_P(p) = IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE; } else { zend_string *save = Z_STR_P(p); char *slash; int actual_len = Z_STRLEN_P(p); - if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) && (slash = (char *)zend_memrchr(actual, '\\', actual_len))) { + if ((Z_CONST_FLAGS_P(p) & IS_CONSTANT_UNQUALIFIED) && (slash = (char *)zend_memrchr(actual, '\\', actual_len))) { actual = slash + 1; actual_len -= (actual - Z_STRVAL_P(p)); if (inline_change) { zend_string *s = STR_INIT(actual, actual_len, 0); //??? STR_RELEASE(Z_STR_P(p)); Z_STR_P(p) = s; + Z_TYPE_FLAGS_P(p) = IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE; } } if (actual[0] == '\\') { @@ -549,7 +551,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope } --actual_len; } - if ((Z_TYPE_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) { + if ((Z_CONST_FLAGS_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) { if (save->val[0] == '\\') { zend_error(E_ERROR, "Undefined constant '%s'", save->val + 1); } else { @@ -561,11 +563,14 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope save = NULL; } zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); - Z_TYPE_P(p) = IS_STRING; if (!inline_change) { ZVAL_STRINGL(p, actual, actual_len); - } else if (save && save->val != actual) { - STR_RELEASE(save); + } else { + Z_TYPE_INFO_P(p) = IS_INTERNED(Z_STR_P(p)) ? + IS_INTERNED_STRING_EX : IS_STRING_EX; + if (save && save->val != actual) { + STR_RELEASE(save); + } } } } else { @@ -585,7 +590,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope SEPARATE_ZVAL_IF_NOT_REF(p); - Z_TYPE_P(p) = IS_ARRAY; + Z_TYPE_INFO_P(p) = IS_ARRAY_EX; if (!inline_change) { HashTable *ht = Z_ARRVAL_P(p); ZVAL_NEW_ARR(p); @@ -1147,7 +1152,7 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s int retval; if (retval_ptr) { - ZVAL_STR(&pv, STR_ALLOC(str_len + sizeof("return ;")-1, 1)); + ZVAL_NEW_STR(&pv, STR_ALLOC(str_len + sizeof("return ;")-1, 1)); memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1); memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, str, str_len); Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';'; -- cgit v1.2.1 From 3d17219cd88a73306acd6eeff8cbae02868318c6 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 7 Apr 2014 23:14:17 +0400 Subject: Refactored zend_hash_* iteration API zend_hash_fove_forward_ex(ht, pos) and family require second argument to be real pointer. &(ht)->nInternalPointer should be passed instead of NULL. zend_hash_update_current_key() may work only with internal pointer. --- Zend/zend_execute_API.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index a56b32a6f4..018e473995 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -601,7 +601,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope /* First go over the array and see if there are any constant indices */ zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); while ((element = zend_hash_get_current_data(Z_ARRVAL_P(p))) != NULL) { - if (zend_hash_get_current_key_ex(Z_ARRVAL_P(p), &str_index, &num_index, 0, NULL) != HASH_KEY_IS_STRING) { + if (zend_hash_get_current_key(Z_ARRVAL_P(p), &str_index, &num_index, 0) != HASH_KEY_IS_STRING) { zend_hash_move_forward(Z_ARRVAL_P(p)); continue; } @@ -666,17 +666,17 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope switch (Z_TYPE(const_value)) { case IS_STRING: - ret = zend_symtable_update_current_key(Z_ARRVAL_P(p), Z_STR(const_value), HASH_UPDATE_KEY_IF_BEFORE); + ret = zend_symtable_update_current_key_ex(Z_ARRVAL_P(p), Z_STR(const_value), HASH_UPDATE_KEY_IF_BEFORE); break; case IS_BOOL: case IS_LONG: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, Z_LVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL); + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, Z_LVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE); break; case IS_DOUBLE: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, zend_dval_to_lval(Z_DVAL(const_value)), HASH_UPDATE_KEY_IF_BEFORE, NULL); + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, zend_dval_to_lval(Z_DVAL(const_value)), HASH_UPDATE_KEY_IF_BEFORE); break; case IS_NULL: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, STR_EMPTY_ALLOC(), 0, HASH_UPDATE_KEY_IF_BEFORE, NULL); + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, STR_EMPTY_ALLOC(), 0, HASH_UPDATE_KEY_IF_BEFORE); break; default: ret = SUCCESS; -- cgit v1.2.1 From 7402af380b3a700dda0e89470770fde15bd56204 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 9 Apr 2014 01:50:15 +0400 Subject: Fixed destruction of objects and iterators on unclean request shutdown and GC (few cases are still unfixed). Now we destroy objects it two steps. At first - object properties of all objects and only then the objects their selves. --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 018e473995..cf321398f8 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -843,7 +843,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EX(object) = fci->object = fci_cache->object; if (fci->object && (!EG(objects_store).object_buckets || - !IS_VALID(EG(objects_store).object_buckets[fci->object->handle]))) { + !IS_OBJ_VALID(EG(objects_store).object_buckets[fci->object->handle]))) { return FAILURE; } -- cgit v1.2.1 From 91ed685e26e0f2e6501ac3c7b49199080bfc47f0 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 11 Apr 2014 02:22:00 +0400 Subject: Close all files and resources before before destroying object storage, because resources may point to objects. (THIS CHANGE MAY BE DANGEROUS) --- Zend/zend_execute_API.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index cf321398f8..2ae2bff70e 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -312,6 +312,14 @@ void shutdown_executor(TSRMLS_D) /* {{{ */ } } zend_end_try(); + zend_try { + zend_llist_destroy(&CG(open_files)); + } zend_end_try(); + + zend_try { + zend_close_rsrc_list(&EG(regular_list) TSRMLS_CC); + } zend_end_try(); + zend_try { zend_objects_store_free_object_storage(&EG(objects_store) TSRMLS_CC); -- cgit v1.2.1 From f614fc68984b2d7fce3f275b8106955b5d910472 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 11 Apr 2014 10:06:17 +0200 Subject: Fix bug #66015 by reverting "Removed operations on constant arrays." --- Zend/zend_execute_API.c | 119 +----------------------------------------------- 1 file changed, 1 insertion(+), 118 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 5d5153dc13..692ec83cc3 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -451,24 +451,11 @@ ZEND_API int zend_is_true(zval *op) /* {{{ */ #include "../TSRM/tsrm_strtok_r.h" -#define IS_VISITED_CONSTANT IS_CONSTANT_INDEX +#define IS_VISITED_CONSTANT 0x80 #define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT) #define Z_REAL_TYPE_P(p) (Z_TYPE_P(p) & ~IS_VISITED_CONSTANT) #define MARK_CONSTANT_VISITED(p) Z_TYPE_P(p) |= IS_VISITED_CONSTANT -static void zval_deep_copy(zval **p) -{ - zval *value; - - ALLOC_ZVAL(value); - *value = **p; - Z_TYPE_P(value) &= ~IS_CONSTANT_INDEX; - zval_copy_ctor(value); - Z_TYPE_P(value) = Z_TYPE_PP(p); - INIT_PZVAL(value); - *p = value; -} - ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC) /* {{{ */ { zval *p = *pp; @@ -559,110 +546,6 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco Z_SET_REFCOUNT_P(p, refcount); Z_SET_ISREF_TO_P(p, is_ref); - } else if (Z_TYPE_P(p) == IS_CONSTANT_ARRAY) { - zval **element, *new_val; - char *str_index; - uint str_index_len; - ulong num_index; - int ret; - - SEPARATE_ZVAL_IF_NOT_REF(pp); - p = *pp; - Z_TYPE_P(p) = IS_ARRAY; - - if (!inline_change) { - zval *tmp; - HashTable *tmp_ht = NULL; - - ALLOC_HASHTABLE(tmp_ht); - zend_hash_init(tmp_ht, zend_hash_num_elements(Z_ARRVAL_P(p)), NULL, ZVAL_PTR_DTOR, 0); - zend_hash_copy(tmp_ht, Z_ARRVAL_P(p), (copy_ctor_func_t) zval_deep_copy, (void *) &tmp, sizeof(zval *)); - Z_ARRVAL_P(p) = tmp_ht; - } - - /* First go over the array and see if there are any constant indices */ - zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); - while (zend_hash_get_current_data(Z_ARRVAL_P(p), (void **) &element) == SUCCESS) { - if (!(Z_TYPE_PP(element) & IS_CONSTANT_INDEX)) { - zend_hash_move_forward(Z_ARRVAL_P(p)); - continue; - } - Z_TYPE_PP(element) &= ~IS_CONSTANT_INDEX; - if (zend_hash_get_current_key_ex(Z_ARRVAL_P(p), &str_index, &str_index_len, &num_index, 0, NULL) != HASH_KEY_IS_STRING) { - zend_hash_move_forward(Z_ARRVAL_P(p)); - continue; - } - if (str_index[str_index_len - 2] == IS_CONSTANT_AST) { - zend_ast_evaluate(&const_value, *(zend_ast **)str_index, scope TSRMLS_CC); - zend_ast_destroy(*(zend_ast **)str_index); - } else if (!zend_get_constant_ex(str_index, str_index_len - 3, &const_value, scope, str_index[str_index_len - 2] TSRMLS_CC)) { - char *actual; - const char *save = str_index; - if ((colon = (char*)zend_memrchr(str_index, ':', str_index_len - 3))) { - zend_error(E_ERROR, "Undefined class constant '%s'", str_index); - str_index_len -= ((colon - str_index) + 1); - str_index = colon; - } else { - if (str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) { - if ((actual = (char *)zend_memrchr(str_index, '\\', str_index_len - 3))) { - actual++; - str_index_len -= (actual - str_index); - str_index = actual; - } - } - if (str_index[0] == '\\') { - ++str_index; - --str_index_len; - } - if (save[0] == '\\') { - ++save; - } - if ((str_index[str_index_len - 2] & IS_CONSTANT_UNQUALIFIED) == 0) { - zend_error(E_ERROR, "Undefined constant '%s'", save); - } - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str_index, str_index); - } - ZVAL_STRINGL(&const_value, str_index, str_index_len-3, 1); - } - - if (Z_REFCOUNT_PP(element) > 1) { - ALLOC_ZVAL(new_val); - *new_val = **element; - zval_copy_ctor(new_val); - Z_SET_REFCOUNT_P(new_val, 1); - Z_UNSET_ISREF_P(new_val); - - /* preserve this bit for inheritance */ - Z_TYPE_PP(element) |= IS_CONSTANT_INDEX; - zval_ptr_dtor(element); - *element = new_val; - } - - switch (Z_TYPE(const_value)) { - case IS_STRING: - ret = zend_symtable_update_current_key(Z_ARRVAL_P(p), Z_STRVAL(const_value), Z_STRLEN(const_value) + 1, HASH_UPDATE_KEY_IF_BEFORE); - break; - case IS_BOOL: - case IS_LONG: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, Z_LVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE, NULL); - break; - case IS_DOUBLE: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, zend_dval_to_lval(Z_DVAL(const_value)), HASH_UPDATE_KEY_IF_BEFORE, NULL); - break; - case IS_NULL: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, "", 1, 0, HASH_UPDATE_KEY_IF_BEFORE, NULL); - break; - default: - ret = SUCCESS; - break; - } - if (ret == SUCCESS) { - zend_hash_move_forward(Z_ARRVAL_P(p)); - } - zval_dtor(&const_value); - } - zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC); - zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) { SEPARATE_ZVAL_IF_NOT_REF(pp); p = *pp; -- cgit v1.2.1 From 35b895fdf0fd2b4fe9ba0e9e7edc513a0a39e205 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Fri, 11 Apr 2014 19:18:58 +0200 Subject: Removed useless void* parameter and replaced with zend_bool on zval_update_constant* functions --- Zend/zend_execute_API.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 692ec83cc3..c9de6b93ca 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -456,10 +456,9 @@ ZEND_API int zend_is_true(zval *op) /* {{{ */ #define Z_REAL_TYPE_P(p) (Z_TYPE_P(p) & ~IS_VISITED_CONSTANT) #define MARK_CONSTANT_VISITED(p) Z_TYPE_P(p) |= IS_VISITED_CONSTANT -ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *scope TSRMLS_DC) /* {{{ */ +ZEND_API int zval_update_constant_ex(zval **pp, zend_bool inline_change, zend_class_entry *scope TSRMLS_DC) /* {{{ */ { zval *p = *pp; - zend_bool inline_change = (zend_bool) (zend_uintptr_t) arg; zval const_value; char *colon; @@ -560,21 +559,21 @@ ZEND_API int zval_update_constant_ex(zval **pp, void *arg, zend_class_entry *sco } /* }}} */ -ZEND_API int zval_update_constant_inline_change(zval **pp, void *scope TSRMLS_DC) /* {{{ */ +ZEND_API int zval_update_constant_inline_change(zval **pp, zend_class_entry *scope TSRMLS_DC) /* {{{ */ { - return zval_update_constant_ex(pp, (void*)1, scope TSRMLS_CC); + return zval_update_constant_ex(pp, 1, scope TSRMLS_CC); } /* }}} */ -ZEND_API int zval_update_constant_no_inline_change(zval **pp, void *scope TSRMLS_DC) /* {{{ */ +ZEND_API int zval_update_constant_no_inline_change(zval **pp, zend_class_entry *scope TSRMLS_DC) /* {{{ */ { - return zval_update_constant_ex(pp, (void*)0, scope TSRMLS_CC); + return zval_update_constant_ex(pp, 0, scope TSRMLS_CC); } /* }}} */ -ZEND_API int zval_update_constant(zval **pp, void *arg TSRMLS_DC) /* {{{ */ +ZEND_API int zval_update_constant(zval **pp, zend_bool inline_change TSRMLS_DC) /* {{{ */ { - return zval_update_constant_ex(pp, arg, NULL TSRMLS_CC); + return zval_update_constant_ex(pp, inline_change, NULL TSRMLS_CC); } /* }}} */ -- cgit v1.2.1 From 050d7e38ad4163e7fa65e26724d3516ce7b33601 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 15 Apr 2014 15:40:40 +0400 Subject: Cleanup (1-st round) --- Zend/zend_execute_API.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 2ae2bff70e..fce8c85ea5 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -465,12 +465,6 @@ ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ * Z_DELREF_P(zval_ptr); if (Z_REFCOUNT_P(zval_ptr) == 0) { _zval_internal_dtor_for_ptr(zval_ptr ZEND_FILE_LINE_CC); -//??? } else if (Z_REFCOUNT_P(zval_ptr) == 1) { -//??? if (Z_ISREF_P(zval_ptr)) { -//??? zend_reference *ref = Z_REF_P(zval_ptr); -//??? ZVAL_COPY_VALUE(zval_ptr, Z_REFVAL_P(zval_ptr)); -//??? efree(ref); -//??? } } } } @@ -484,20 +478,18 @@ ZEND_API int zend_is_true(zval *op TSRMLS_DC) /* {{{ */ #include "../TSRM/tsrm_strtok_r.h" -#define IS_VISITED_CONSTANT 0x080 //??? IS_CONSTANT_INDEX +#define IS_VISITED_CONSTANT 0x080 #define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT) #define Z_REAL_TYPE_P(p) (Z_TYPE_P(p) & ~IS_VISITED_CONSTANT) #define MARK_CONSTANT_VISITED(p) Z_TYPE_INFO_P(p) |= IS_VISITED_CONSTANT static void zval_deep_copy(zval *p) { - zval value; - - ZVAL_DUP(&value, p); -//??? Z_TYPE(value) &= ~IS_CONSTANT_INDEX; -//??? zval_copy_ctor(&value); -//??? Z_TYPE(value) = Z_TYPE_P(p); - ZVAL_COPY_VALUE(p, &value); +//??? zval value; +//??? +//??? ZVAL_DUP(&value, p); +//??? ZVAL_COPY_VALUE(p, &value); + zval_copy_ctor(p); } ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope TSRMLS_DC) /* {{{ */ @@ -1200,7 +1192,7 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s CG(interactive) = orig_interactive; if (Z_TYPE(local_retval) != IS_UNDEF) { if (retval_ptr) { - COPY_PZVAL_TO_ZVAL(*retval_ptr, &local_retval); + ZVAL_COPY_VALUE(retval_ptr, &local_retval); } else { zval_ptr_dtor(&local_retval); } -- cgit v1.2.1 From f9b26bc39a9ea9b1380628eeb0e6dad3c93cfcb0 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 15 Apr 2014 21:56:30 +0400 Subject: Cleanup (2-nd round) --- Zend/zend_execute_API.c | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index fce8c85ea5..31caf41789 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -483,15 +483,6 @@ ZEND_API int zend_is_true(zval *op TSRMLS_DC) /* {{{ */ #define Z_REAL_TYPE_P(p) (Z_TYPE_P(p) & ~IS_VISITED_CONSTANT) #define MARK_CONSTANT_VISITED(p) Z_TYPE_INFO_P(p) |= IS_VISITED_CONSTANT -static void zval_deep_copy(zval *p) -{ -//??? zval value; -//??? -//??? ZVAL_DUP(&value, p); -//??? ZVAL_COPY_VALUE(p, &value); - zval_copy_ctor(p); -} - ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope TSRMLS_DC) /* {{{ */ { zend_bool inline_change = (zend_bool) (zend_uintptr_t) arg; @@ -502,15 +493,10 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope zend_error(E_ERROR, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p)); } else if (Z_TYPE_P(p) == IS_CONSTANT) { int refcount; -//??? zend_uchar is_ref; SEPARATE_ZVAL_IF_NOT_REF(p); - MARK_CONSTANT_VISITED(p); - refcount = Z_REFCOUNTED_P(p) ? Z_REFCOUNT_P(p) : 1; -//??? is_ref = Z_ISREF_P(p); - if (!zend_get_constant_ex(Z_STRVAL_P(p), Z_STRLEN_P(p), &const_value, scope, Z_CONST_FLAGS_P(p) TSRMLS_CC)) { char *actual = Z_STRVAL_P(p); @@ -524,7 +510,6 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope STR_RELEASE(Z_STR_P(p)); Z_STR_P(p) = tmp; } else { -//??? Z_STRVAL_P(p) = colon + 1; Z_STR_P(p) = STR_INIT(colon + 1, len, 0); } Z_TYPE_FLAGS_P(p) = IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE; @@ -581,7 +566,6 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope } if (Z_REFCOUNTED_P(p)) Z_SET_REFCOUNT_P(p, refcount); -//??? Z_SET_ISREF_TO_P(p, is_ref); } else if (Z_TYPE_P(p) == IS_CONSTANT_ARRAY) { zval *element, new_val; zend_string *str_index; @@ -595,7 +579,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope HashTable *ht = Z_ARRVAL_P(p); ZVAL_NEW_ARR(p); zend_hash_init(Z_ARRVAL_P(p), zend_hash_num_elements(ht), NULL, ZVAL_PTR_DTOR, 0); - zend_hash_copy(Z_ARRVAL_P(p), ht, zval_deep_copy); + zend_hash_copy(Z_ARRVAL_P(p), ht, ZVAL_COPY_CTOR); } /* First go over the array and see if there are any constant indices */ @@ -616,7 +600,6 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope zend_ast_evaluate(&const_value, ast->ast, scope TSRMLS_CC); zend_ast_destroy(ast->ast); efree(ast); -//??? } else if (!zend_get_constant_ex(str_index->val, str_index->len, &const_value, scope, GC_FLAGS(str_index) & ~(IS_STR_PERSISTENT | IS_STR_INTERNED |IS_STR_PERMANENT) TSRMLS_CC)) { char *actual, *str; const char *save = str_index->val; @@ -657,9 +640,6 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope if (Z_REFCOUNTED_P(element) && Z_REFCOUNT_P(element) > 1) { ZVAL_DUP(&new_val, element); - - /* preserve this bit for inheritance */ -//??? Z_TYPE_P(element) |= IS_CONSTANT_INDEX; zval_ptr_dtor(element); ZVAL_COPY_VALUE(element, &new_val); } @@ -990,7 +970,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS fci_cache->initialized = 0; } } else { /* ZEND_OVERLOADED_FUNCTION */ -//??? ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr); + ZVAL_NULL(fci->retval); /* Not sure what should be done here if it's a static method */ if (fci->object) { -- cgit v1.2.1 From e99e6958bc8db305bb5697a25ea222d2aab16362 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 16 Apr 2014 01:45:40 +0400 Subject: Cleanup --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 31caf41789..2db5fd397c 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -522,7 +522,7 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope actual_len -= (actual - Z_STRVAL_P(p)); if (inline_change) { zend_string *s = STR_INIT(actual, actual_len, 0); -//??? STR_RELEASE(Z_STR_P(p)); + STR_RELEASE(Z_STR_P(p)); Z_STR_P(p) = s; Z_TYPE_FLAGS_P(p) = IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE; } -- cgit v1.2.1 From fb4e0a63643e03f23e4a1a24892b93635566184a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 16 Apr 2014 12:28:20 +0400 Subject: Removed invalid STR_RELEASE() --- Zend/zend_execute_API.c | 1 - 1 file changed, 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 2db5fd397c..a72fb5dd6d 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -522,7 +522,6 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope actual_len -= (actual - Z_STRVAL_P(p)); if (inline_change) { zend_string *s = STR_INIT(actual, actual_len, 0); - STR_RELEASE(Z_STR_P(p)); Z_STR_P(p) = s; Z_TYPE_FLAGS_P(p) = IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE; } -- cgit v1.2.1 From e96073b1e40c4999dee70db684721a582ea5e055 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 17 Apr 2014 15:40:45 +0400 Subject: Moved zend_literal->cache_slot right into zval. It should be accessed using Z_CACHE_SLOT() macro. zend_literal structure is removed. API functions that accepted pointer to zend_literal now accept pointer to zval or cache_slot directly. Calls of such functiond that now accept cache_slot need to be changed to pass -1 instead of NULL. --- Zend/zend_execute_API.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index a72fb5dd6d..0c6861c14d 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1005,7 +1005,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } /* }}} */ -ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zend_literal *key, int use_autoload TSRMLS_DC) /* {{{ */ +ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *key, int use_autoload TSRMLS_DC) /* {{{ */ { zend_class_entry *ce = NULL; zval args[1]; @@ -1016,7 +1016,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zend_li zend_fcall_info_cache fcall_cache; if (key) { - lc_name = Z_STR(key->constant); + lc_name = Z_STR_P(key); } else { if (name == NULL || !name->len) { return NULL; @@ -1248,10 +1248,10 @@ void execute_new_code(TSRMLS_D) /* {{{ */ while (oplineop1_type == IS_CONST) { - opline->op1.zv = &CG(active_op_array)->literals[opline->op1.constant].constant; + opline->op1.zv = &CG(active_op_array)->literals[opline->op1.constant]; } if (opline->op2_type == IS_CONST) { - opline->op2.zv = &CG(active_op_array)->literals[opline->op2.constant].constant; + opline->op2.zv = &CG(active_op_array)->literals[opline->op2.constant]; } switch (opline->opcode) { case ZEND_GOTO: @@ -1560,7 +1560,7 @@ check_fetch_type: } /* }}} */ -zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, const zend_literal *key, int fetch_type TSRMLS_DC) /* {{{ */ +zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, const zval *key, int fetch_type TSRMLS_DC) /* {{{ */ { zend_class_entry *ce; int use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) == 0; -- cgit v1.2.1 From ea2e1bb1eb7dd0ca1ce6d731190b2a6b2046a645 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 18 Apr 2014 13:46:36 +0400 Subject: Optimized zend_leave_helper() --- Zend/zend_execute_API.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 0c6861c14d..8d5b55c84d 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -935,12 +935,12 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_execute(EG(active_op_array), fci->retval TSRMLS_CC); } + EG(active_op_array) = original_op_array; + EG(opline_ptr) = original_opline_ptr; if (!fci->symbol_table && EG(active_symbol_table)) { zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC); } EG(active_symbol_table) = calling_symbol_table; - EG(active_op_array) = original_op_array; - EG(opline_ptr) = original_opline_ptr; } else if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { int call_via_handler = (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0; ZVAL_NULL(fci->retval); @@ -1695,12 +1695,11 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ } /* }}} */ -ZEND_API void zend_attach_symbol_table(TSRMLS_D) /* {{{ */ +ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data) /* {{{ */ { int i; - zend_execute_data *execute_data = EG(current_execute_data); zend_op_array *op_array = execute_data->op_array; - HashTable *ht = &EG(active_symbol_table)->ht; + HashTable *ht = &execute_data->symbol_table->ht; /* copy real values from symbol table into CV slots and create INDIRECT references to CV in symbol table */ @@ -1727,12 +1726,11 @@ ZEND_API void zend_attach_symbol_table(TSRMLS_D) /* {{{ */ } /* }}} */ -ZEND_API void zend_detach_symbol_table(TSRMLS_D) /* {{{ */ +ZEND_API void zend_detach_symbol_table(zend_execute_data *execute_data) /* {{{ */ { int i; - zend_execute_data *execute_data = EG(current_execute_data); zend_op_array *op_array = execute_data->op_array; - HashTable *ht = &EG(active_symbol_table)->ht; + HashTable *ht = &execute_data->symbol_table->ht; /* copy real values from CV slots into symbol table */ for (i = 0; i < op_array->last_var; i++) { -- cgit v1.2.1 From f71da39210ef29c409f3ed9fe0044e5f75263f78 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 21 Apr 2014 13:55:25 +0400 Subject: Use ZEND_HASH_FOEACH_* instead of zend_hash_apply_* --- Zend/zend_execute_API.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 8d5b55c84d..f976a80705 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -245,6 +245,9 @@ void shutdown_destructors(TSRMLS_D) /* {{{ */ void shutdown_executor(TSRMLS_D) /* {{{ */ { + zend_function *func; + zend_class_entry *ce; + zend_try { /* Removed because this can not be safely done, e.g. in this situation: @@ -303,11 +306,31 @@ void shutdown_executor(TSRMLS_D) /* {{{ */ * Note that only run-time accessed data need to be cleaned up, pre-defined data can * not contain objects and thus are not probelmatic */ if (EG(full_tables_cleanup)) { - zend_hash_apply(EG(function_table), zend_cleanup_function_data_full TSRMLS_CC); - zend_hash_apply(EG(class_table), zend_cleanup_class_data TSRMLS_CC); + ZEND_HASH_FOREACH_PTR(EG(function_table), func) { + if (func->type == ZEND_USER_FUNCTION) { + zend_cleanup_op_array_data((zend_op_array *) func); + } + } ZEND_HASH_FOREACH_END(); + ZEND_HASH_REVERSE_FOREACH_PTR(EG(class_table), ce) { + if (ce->type == ZEND_USER_CLASS) { + zend_cleanup_user_class_data(ce TSRMLS_CC); + } else { + zend_cleanup_internal_class_data(ce TSRMLS_CC); + } + } ZEND_HASH_FOREACH_END(); } else { - zend_hash_reverse_apply(EG(function_table), zend_cleanup_function_data TSRMLS_CC); - zend_hash_reverse_apply(EG(class_table), zend_cleanup_user_class_data TSRMLS_CC); + ZEND_HASH_REVERSE_FOREACH_PTR(EG(function_table), func) { + if (func->type != ZEND_USER_FUNCTION) { + break; + } + zend_cleanup_op_array_data((zend_op_array *) func); + } ZEND_HASH_FOREACH_END(); + ZEND_HASH_REVERSE_FOREACH_PTR(EG(class_table), ce) { + if (ce->type != ZEND_USER_CLASS) { + break; + } + zend_cleanup_user_class_data(ce TSRMLS_CC); + } ZEND_HASH_FOREACH_END(); zend_cleanup_internal_classes(TSRMLS_C); } } zend_end_try(); -- cgit v1.2.1 From 72c287bd232ef3a0dc5ae76a4b5b5879a8ee7786 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 21 Apr 2014 18:25:34 +0400 Subject: Combine HashTable.flags and HashTable.nApplyCount into single 32-bit word --- Zend/zend_execute_API.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index f976a80705..44e3f08895 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -160,13 +160,13 @@ void init_executor(TSRMLS_D) /* {{{ */ ZVAL_LONG(&tmp, 0); zend_vm_stack_push(&tmp TSRMLS_CC); - zend_hash_init(&EG(symbol_table).ht, 50, NULL, ZVAL_PTR_DTOR, 0); + zend_hash_init(&EG(symbol_table).ht, 64, NULL, ZVAL_PTR_DTOR, 0); EG(active_symbol_table) = &EG(symbol_table); zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator TSRMLS_CC); EG(opline_ptr) = NULL; - zend_hash_init(&EG(included_files), 5, NULL, NULL, 0); + zend_hash_init(&EG(included_files), 8, NULL, NULL, 0); EG(ticks_count) = 0; @@ -1082,7 +1082,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k if (EG(in_autoload) == NULL) { ALLOC_HASHTABLE(EG(in_autoload)); - zend_hash_init(EG(in_autoload), 0, NULL, NULL, 0); + zend_hash_init(EG(in_autoload), 8, NULL, NULL, 0); } if (zend_hash_add_empty_element(EG(in_autoload), lc_name) == NULL) { -- cgit v1.2.1 From 1f181c0f4cce794461bbbed3b580d7d0d0a63ee9 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 22 Apr 2014 01:41:40 +0400 Subject: Chiper __autoload() function caching --- Zend/zend_execute_API.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 44e3f08895..0091fea00d 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1072,6 +1072,19 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k return NULL; } + if (!EG(autoload_func)) { + zend_function *func = zend_hash_str_find_ptr(EG(function_table), ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1); + if (func) { + EG(autoload_func) = func; + } else { + if (!key) { + STR_FREE(lc_name); + } + return NULL; + } + + } + /* Verify class name before passing it to __autoload() */ if (strspn(name->val, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\") != name->len) { if (!key) { @@ -1102,7 +1115,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k fcall_info.size = sizeof(fcall_info); fcall_info.function_table = EG(function_table); - ZVAL_STRINGL(&fcall_info.function_name, ZEND_AUTOLOAD_FUNC_NAME, sizeof(ZEND_AUTOLOAD_FUNC_NAME) - 1); + ZVAL_STR(&fcall_info.function_name, STR_COPY(EG(autoload_func)->common.function_name)); fcall_info.symbol_table = NULL; fcall_info.retval = &local_retval; fcall_info.param_count = 1; @@ -1110,7 +1123,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k fcall_info.object = NULL; fcall_info.no_separation = 1; - fcall_cache.initialized = EG(autoload_func) ? 1 : 0; + fcall_cache.initialized = 1; fcall_cache.function_handler = EG(autoload_func); fcall_cache.calling_scope = NULL; fcall_cache.called_scope = NULL; @@ -1120,8 +1133,6 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k retval = zend_call_function(&fcall_info, &fcall_cache TSRMLS_CC); zend_exception_restore(TSRMLS_C); - EG(autoload_func) = fcall_cache.function_handler; - zval_ptr_dtor(&args[0]); zval_dtor(&fcall_info.function_name); -- cgit v1.2.1 From 65e2ed6e50d210adb50de47ef7ac3b75af069f62 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 24 Apr 2014 15:53:20 +0400 Subject: Redesigned zend_execute_data layout now EX(object), EX(scope) and EX(called_scope) arr properties of the current function execution co ntext. They are set during zend_execute_data initialization and never changed. --- Zend/zend_execute_API.c | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 0091fea00d..d2fefa7f71 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -770,11 +770,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_array *calling_symbol_table; zend_op_array *original_op_array; zend_op **original_opline_ptr; - zend_class_entry *current_scope; - zend_class_entry *current_called_scope; zend_class_entry *calling_scope = NULL; zend_class_entry *called_scope = NULL; - zend_object *current_this; zend_execute_data execute_data; zend_fcall_info_cache fci_cache_local; zval tmp; @@ -800,9 +797,11 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS /* Initialize execute_data */ if (EG(current_execute_data)) { execute_data = *EG(current_execute_data); + EX(object) = Z_OBJ(EG(This)); + EX(scope) = EG(scope); + EX(called_scope) = EG(called_scope); EX(op_array) = NULL; EX(opline) = NULL; - EX(object) = NULL; } else { /* This only happens when we're called outside any execute()'s * It shouldn't be strictly necessary to NULL execute_data out, @@ -842,7 +841,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EX(function_state).function = fci_cache->function_handler; calling_scope = fci_cache->calling_scope; called_scope = fci_cache->called_scope; - EX(object) = fci->object = fci_cache->object; + fci->object = fci_cache->object; if (fci->object && (!EG(objects_store).object_buckets || !IS_OBJ_VALID(EG(objects_store).object_buckets[fci->object->handle]))) { @@ -916,18 +915,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS ZVAL_LONG(&tmp, fci->param_count); zend_vm_stack_push(&tmp TSRMLS_CC); - current_scope = EG(scope); EG(scope) = calling_scope; - - current_this = Z_OBJ(EG(This)); - - current_called_scope = EG(called_scope); - if (called_scope) { - EG(called_scope) = called_scope; - } else if (EX(function_state).function->type != ZEND_INTERNAL_FUNCTION) { - EG(called_scope) = NULL; - } - + EG(called_scope) = called_scope; if (!fci->object || (EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)) { Z_OBJ(EG(This)) = NULL; @@ -1016,9 +1005,10 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS if (Z_OBJ(EG(This))) { zval_ptr_dtor(&EG(This)); } - EG(called_scope) = current_called_scope; - EG(scope) = current_scope; - Z_OBJ(EG(This)) = current_this; + + Z_OBJ(EG(This)) = EX(object); + EG(scope) = EX(scope); + EG(called_scope) = EX(called_scope); EG(current_execute_data) = EX(prev_execute_data); if (EG(exception)) { @@ -1711,12 +1701,6 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ /*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/ } ex->symbol_table = EG(active_symbol_table); - - if (ex->op_array->this_var != -1 && - Z_TYPE_P(EX_VAR_2(ex, ex->op_array->this_var)) == IS_UNDEF && - Z_OBJ(EG(This))) { - ZVAL_COPY_VALUE(EX_VAR_2(ex, ex->op_array->this_var), &EG(This)); - } for (i = 0; i < ex->op_array->last_var; i++) { zval zv; -- cgit v1.2.1 From df7ca608ce62dba76ab7c766bede2a3f9b68755e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 25 Apr 2014 00:56:15 +0400 Subject: Optimized constant lookup --- Zend/zend_execute_API.c | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index d2fefa7f71..3ad4a8cac1 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -509,7 +509,7 @@ ZEND_API int zend_is_true(zval *op TSRMLS_DC) /* {{{ */ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope TSRMLS_DC) /* {{{ */ { zend_bool inline_change = (zend_bool) (zend_uintptr_t) arg; - zval const_value; + zval *const_value, tmp; char *colon; if (IS_CONSTANT_VISITED(p)) { @@ -520,7 +520,8 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope SEPARATE_ZVAL_IF_NOT_REF(p); MARK_CONSTANT_VISITED(p); refcount = Z_REFCOUNTED_P(p) ? Z_REFCOUNT_P(p) : 1; - if (!zend_get_constant_ex(Z_STRVAL_P(p), Z_STRLEN_P(p), &const_value, scope, Z_CONST_FLAGS_P(p) TSRMLS_CC)) { + const_value = zend_get_constant_ex(Z_STR_P(p), scope, Z_CONST_FLAGS_P(p) TSRMLS_CC); + if (!const_value) { char *actual = Z_STRVAL_P(p); if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) { @@ -584,7 +585,12 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope if (inline_change) { STR_RELEASE(Z_STR_P(p)); } - ZVAL_COPY_VALUE(p, &const_value); +//???! + ZVAL_COPY_VALUE(p, const_value); + if (Z_OPT_CONSTANT_P(p)) { + zval_update_constant_ex(p, (void*)1, NULL TSRMLS_CC); + } + zval_opt_copy_ctor(p); } if (Z_REFCOUNTED_P(p)) Z_SET_REFCOUNT_P(p, refcount); @@ -619,10 +625,11 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope if (GC_FLAGS(str_index) & IS_STR_AST) { zend_ast_ref *ast = *(zend_ast_ref **)str_index->val; - zend_ast_evaluate(&const_value, ast->ast, scope TSRMLS_CC); + zend_ast_evaluate(&tmp, ast->ast, scope TSRMLS_CC); zend_ast_destroy(ast->ast); efree(ast); - } else if (!zend_get_constant_ex(str_index->val, str_index->len, &const_value, scope, GC_FLAGS(str_index) & ~(IS_STR_PERSISTENT | IS_STR_INTERNED |IS_STR_PERMANENT) TSRMLS_CC)) { + const_value = &tmp; + } else if (!(const_value = zend_get_constant_ex(str_index, scope, GC_FLAGS(str_index) & ~(IS_STR_PERSISTENT | IS_STR_INTERNED |IS_STR_PERMANENT) TSRMLS_CC))) { char *actual, *str; const char *save = str_index->val; int len; @@ -654,10 +661,19 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str, str); } if (str == str_index->val && len == str_index->len) { - ZVAL_STR(&const_value, STR_COPY(str_index)); + ZVAL_STR(&tmp, STR_COPY(str_index)); } else { - ZVAL_STRINGL(&const_value, str, len); + ZVAL_STRINGL(&tmp, str, len); + } + const_value = &tmp; + } else { +//???! + ZVAL_COPY_VALUE(&tmp, const_value); + if (Z_OPT_CONSTANT(tmp)) { + zval_update_constant_ex(&tmp, (void*)1, NULL TSRMLS_CC); } + zval_opt_copy_ctor(&tmp); + const_value = &tmp; } if (Z_REFCOUNTED_P(element) && Z_REFCOUNT_P(element) > 1) { @@ -666,16 +682,16 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope ZVAL_COPY_VALUE(element, &new_val); } - switch (Z_TYPE(const_value)) { + switch (Z_TYPE_P(const_value)) { case IS_STRING: - ret = zend_symtable_update_current_key_ex(Z_ARRVAL_P(p), Z_STR(const_value), HASH_UPDATE_KEY_IF_BEFORE); + ret = zend_symtable_update_current_key_ex(Z_ARRVAL_P(p), Z_STR_P(const_value), HASH_UPDATE_KEY_IF_BEFORE); break; case IS_BOOL: case IS_LONG: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, Z_LVAL(const_value), HASH_UPDATE_KEY_IF_BEFORE); + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, Z_LVAL_P(const_value), HASH_UPDATE_KEY_IF_BEFORE); break; case IS_DOUBLE: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, zend_dval_to_lval(Z_DVAL(const_value)), HASH_UPDATE_KEY_IF_BEFORE); + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, zend_dval_to_lval(Z_DVAL_P(const_value)), HASH_UPDATE_KEY_IF_BEFORE); break; case IS_NULL: ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, STR_EMPTY_ALLOC(), 0, HASH_UPDATE_KEY_IF_BEFORE); @@ -687,19 +703,19 @@ ZEND_API int zval_update_constant_ex(zval *p, void *arg, zend_class_entry *scope if (ret == SUCCESS) { zend_hash_move_forward(Z_ARRVAL_P(p)); } - zval_dtor(&const_value); + zval_dtor(const_value); } zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC); zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) { SEPARATE_ZVAL_IF_NOT_REF(p); - zend_ast_evaluate(&const_value, Z_ASTVAL_P(p), scope TSRMLS_CC); + zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope TSRMLS_CC); if (inline_change) { zend_ast_destroy(Z_ASTVAL_P(p)); efree(Z_AST_P(p)); } - ZVAL_COPY_VALUE(p, &const_value); + ZVAL_COPY_VALUE(p, &tmp); } return 0; } -- cgit v1.2.1 From 4e7cbf3f5842abe6688c11ce3cc11d2eabf0695f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 25 Apr 2014 11:54:10 +0400 Subject: Use appropriate macros --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 3ad4a8cac1..621ad66586 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -359,7 +359,7 @@ void shutdown_executor(TSRMLS_D) /* {{{ */ while (EG(symtable_cache_ptr)>=EG(symtable_cache)) { zend_hash_destroy(&(*EG(symtable_cache_ptr))->ht); - efree(*EG(symtable_cache_ptr)); + FREE_HASHTABLE(*EG(symtable_cache_ptr)); EG(symtable_cache_ptr)--; } } zend_end_try(); -- cgit v1.2.1 From 6a911e833f6b6dcac669a60808e96dc2c4f391d3 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 30 Apr 2014 11:23:19 +0400 Subject: Optimized JMPZNZ to avoid multiplication at runtime (may be it makes sense to use relative addresses everywere it'll lead to Position Independent Code) --- Zend/zend_execute_API.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 03f763ea21..a7d7a948a5 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1301,6 +1301,10 @@ void execute_new_code(TSRMLS_D) /* {{{ */ case ZEND_JMP: opline->op1.jmp_addr = &CG(active_op_array)->opcodes[opline->op1.opline_num]; break; + case ZEND_JMPZNZ: + /* absolute index to relative offset */ + opline->extended_value = (char*)(CG(active_op_array)->opcodes + opline->extended_value) - (char*)opline; + /* break omitted intentionally */ case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: -- cgit v1.2.1 From 17d027ed47c1f07b397a611431d28ad0e0107146 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 30 Apr 2014 18:32:42 +0400 Subject: Split IS_BOOL into IS_FALSE and IS_TRUE --- Zend/zend_execute_API.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index a7d7a948a5..7041563704 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -685,7 +685,12 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas case IS_STRING: ret = zend_symtable_update_current_key_ex(Z_ARRVAL_P(p), Z_STR_P(const_value), HASH_UPDATE_KEY_IF_BEFORE); break; - case IS_BOOL: + case IS_FALSE: + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, HASH_UPDATE_KEY_IF_BEFORE); + break; + case IS_TRUE: + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 1, HASH_UPDATE_KEY_IF_BEFORE); + break; case IS_LONG: ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, Z_LVAL_P(const_value), HASH_UPDATE_KEY_IF_BEFORE); break; -- cgit v1.2.1 From 5a03efe2790cc935d4d8ca723bd21ce8c079fbd4 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 30 Apr 2014 20:28:02 +0200 Subject: Don't allocate zend_stack elements individually Instead allocate a vector of elements. Size must now be specified on initialization rather than on push. --- Zend/zend_execute_API.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 7041563704..ff52993ca0 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -174,9 +174,9 @@ void init_executor(TSRMLS_D) /* {{{ */ EG(current_execute_data) = NULL; - zend_stack_init(&EG(user_error_handlers_error_reporting)); - zend_stack_init(&EG(user_error_handlers)); - zend_stack_init(&EG(user_exception_handlers)); + zend_stack_init(&EG(user_error_handlers_error_reporting), sizeof(int)); + zend_stack_init(&EG(user_error_handlers), sizeof(zval)); + zend_stack_init(&EG(user_exception_handlers), sizeof(zval)); zend_objects_store_init(&EG(objects_store), 1024); @@ -289,8 +289,7 @@ void shutdown_executor(TSRMLS_D) /* {{{ */ ZVAL_UNDEF(&EG(user_exception_handler)); } - zend_stack_destroy(&EG(user_error_handlers_error_reporting)); - zend_stack_init(&EG(user_error_handlers_error_reporting)); + zend_stack_clean(&EG(user_error_handlers_error_reporting), NULL, 1); zend_stack_clean(&EG(user_error_handlers), (void (*)(void *))ZVAL_DESTRUCTOR, 1); zend_stack_clean(&EG(user_exception_handlers), (void (*)(void *))ZVAL_DESTRUCTOR, 1); } zend_end_try(); -- cgit v1.2.1 From 1fa4dcac87c9d5eb887534085b985250a9c1c807 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 6 May 2014 04:35:29 +0400 Subject: Added comment with problem description and two soltions --- Zend/zend_execute_API.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index ff52993ca0..3806af0a05 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -885,7 +885,22 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zval *param; if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)) { + // TODO: Scalar values don't have reference counters anymore. + // They are assumed to be 1, and they may be easily passed by + // reference now. However, previously scalars with refcount==1 + // might be passed and with refcount>1 might not. We can support + // only single behavior ??? +#if 0 + if (Z_REFCOUNTED(fci->params[i]) && + // This solution breaks the following test (omit warning message) ??? + // Zend/tests/bug61273.phpt + // ext/reflection/tests/bug42976.phpt + // ext/standard/tests/general_functions/call_user_func_array_variation_001.phpt +#else if (!Z_REFCOUNTED(fci->params[i]) || + // This solution breaks the following test (emit warning message) ??? + // ext/pdo_sqlite/tests/pdo_005.phpt +#endif (!Z_ISREF(fci->params[i]) && Z_REFCOUNT(fci->params[i]) > 1)) { if (fci->no_separation && -- cgit v1.2.1 From f3c1881f1dc19cb8bd0ddf0c85ecee390fde526f Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Tue, 6 May 2014 14:59:03 +0200 Subject: Re-added fix for bug #66015 and adapted for phpng branch --- Zend/zend_execute_API.c | 118 ------------------------------------------------ 1 file changed, 118 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 3806af0a05..15f79738e6 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -592,124 +592,6 @@ 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_ARRAY) { - zval *element, new_val; - zend_string *str_index; - ulong num_index; - int ret; - - SEPARATE_ZVAL_IF_NOT_REF(p); - - Z_TYPE_INFO_P(p) = IS_ARRAY_EX; - if (!inline_change) { - HashTable *ht = Z_ARRVAL_P(p); - ZVAL_NEW_ARR(p); - zend_hash_init(Z_ARRVAL_P(p), zend_hash_num_elements(ht), NULL, ZVAL_PTR_DTOR, 0); - zend_hash_copy(Z_ARRVAL_P(p), ht, ZVAL_COPY_CTOR); - } - - /* First go over the array and see if there are any constant indices */ - zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); - while ((element = zend_hash_get_current_data(Z_ARRVAL_P(p))) != NULL) { - if (zend_hash_get_current_key(Z_ARRVAL_P(p), &str_index, &num_index, 0) != HASH_KEY_IS_STRING) { - zend_hash_move_forward(Z_ARRVAL_P(p)); - continue; - } - if (!(GC_FLAGS(str_index) & (IS_STR_CONSTANT | IS_STR_AST))) { - zend_hash_move_forward(Z_ARRVAL_P(p)); - continue; - } - - if (GC_FLAGS(str_index) & IS_STR_AST) { - zend_ast_ref *ast = *(zend_ast_ref **)str_index->val; - - zend_ast_evaluate(&tmp, ast->ast, scope TSRMLS_CC); - zend_ast_destroy(ast->ast); - efree(ast); - const_value = &tmp; - } else if (!(const_value = zend_get_constant_ex(str_index, scope, GC_FLAGS(str_index) & ~(IS_STR_PERSISTENT | IS_STR_INTERNED |IS_STR_PERMANENT) TSRMLS_CC))) { - char *actual, *str; - const char *save = str_index->val; - int len; - - str = str_index->val; - len = str_index->len; - if ((colon = (char*)zend_memrchr(str, ':', len))) { - zend_error(E_ERROR, "Undefined class constant '%s'", str); - len -= ((colon - str) + 1); - str = colon; - } else { - if (GC_FLAGS(str_index) & IS_STR_CONSTANT_UNQUALIFIED) { - if ((actual = (char *)zend_memrchr(str, '\\', len))) { - actual++; - len -= (actual - str); - str = actual; - } - } - if (str[0] == '\\') { - ++str; - --len; - } - if (save[0] == '\\') { - ++save; - } - if (!(GC_FLAGS(str_index) & IS_STR_CONSTANT_UNQUALIFIED)) { - zend_error(E_ERROR, "Undefined constant '%s'", save); - } - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str, str); - } - if (str == str_index->val && len == str_index->len) { - ZVAL_STR(&tmp, STR_COPY(str_index)); - } else { - ZVAL_STRINGL(&tmp, str, len); - } - const_value = &tmp; - } else { -//???! - ZVAL_COPY_VALUE(&tmp, const_value); - if (Z_OPT_CONSTANT(tmp)) { - zval_update_constant_ex(&tmp, 1, NULL TSRMLS_CC); - } - zval_opt_copy_ctor(&tmp); - const_value = &tmp; - } - - if (Z_REFCOUNTED_P(element) && Z_REFCOUNT_P(element) > 1) { - ZVAL_DUP(&new_val, element); - zval_ptr_dtor(element); - ZVAL_COPY_VALUE(element, &new_val); - } - - switch (Z_TYPE_P(const_value)) { - case IS_STRING: - ret = zend_symtable_update_current_key_ex(Z_ARRVAL_P(p), Z_STR_P(const_value), HASH_UPDATE_KEY_IF_BEFORE); - break; - case IS_FALSE: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, HASH_UPDATE_KEY_IF_BEFORE); - break; - case IS_TRUE: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 1, HASH_UPDATE_KEY_IF_BEFORE); - break; - case IS_LONG: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, Z_LVAL_P(const_value), HASH_UPDATE_KEY_IF_BEFORE); - break; - case IS_DOUBLE: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, zend_dval_to_lval(Z_DVAL_P(const_value)), HASH_UPDATE_KEY_IF_BEFORE); - break; - case IS_NULL: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, STR_EMPTY_ALLOC(), 0, HASH_UPDATE_KEY_IF_BEFORE); - break; - default: - ret = SUCCESS; - break; - } - if (ret == SUCCESS) { - zend_hash_move_forward(Z_ARRVAL_P(p)); - } - zval_dtor(const_value); - } - zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC); - zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) { SEPARATE_ZVAL_IF_NOT_REF(p); -- cgit v1.2.1 From 4ecc52797650c882f3101edd7171007ac0d15ec7 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 7 May 2014 03:26:13 +0400 Subject: Reverted Bob's patch (it breaks many tests when run with opcache and needs to be fixed first). --- Zend/zend_execute_API.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 15f79738e6..3806af0a05 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -592,6 +592,124 @@ 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_ARRAY) { + zval *element, new_val; + zend_string *str_index; + ulong num_index; + int ret; + + SEPARATE_ZVAL_IF_NOT_REF(p); + + Z_TYPE_INFO_P(p) = IS_ARRAY_EX; + if (!inline_change) { + HashTable *ht = Z_ARRVAL_P(p); + ZVAL_NEW_ARR(p); + zend_hash_init(Z_ARRVAL_P(p), zend_hash_num_elements(ht), NULL, ZVAL_PTR_DTOR, 0); + zend_hash_copy(Z_ARRVAL_P(p), ht, ZVAL_COPY_CTOR); + } + + /* First go over the array and see if there are any constant indices */ + zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); + while ((element = zend_hash_get_current_data(Z_ARRVAL_P(p))) != NULL) { + if (zend_hash_get_current_key(Z_ARRVAL_P(p), &str_index, &num_index, 0) != HASH_KEY_IS_STRING) { + zend_hash_move_forward(Z_ARRVAL_P(p)); + continue; + } + if (!(GC_FLAGS(str_index) & (IS_STR_CONSTANT | IS_STR_AST))) { + zend_hash_move_forward(Z_ARRVAL_P(p)); + continue; + } + + if (GC_FLAGS(str_index) & IS_STR_AST) { + zend_ast_ref *ast = *(zend_ast_ref **)str_index->val; + + zend_ast_evaluate(&tmp, ast->ast, scope TSRMLS_CC); + zend_ast_destroy(ast->ast); + efree(ast); + const_value = &tmp; + } else if (!(const_value = zend_get_constant_ex(str_index, scope, GC_FLAGS(str_index) & ~(IS_STR_PERSISTENT | IS_STR_INTERNED |IS_STR_PERMANENT) TSRMLS_CC))) { + char *actual, *str; + const char *save = str_index->val; + int len; + + str = str_index->val; + len = str_index->len; + if ((colon = (char*)zend_memrchr(str, ':', len))) { + zend_error(E_ERROR, "Undefined class constant '%s'", str); + len -= ((colon - str) + 1); + str = colon; + } else { + if (GC_FLAGS(str_index) & IS_STR_CONSTANT_UNQUALIFIED) { + if ((actual = (char *)zend_memrchr(str, '\\', len))) { + actual++; + len -= (actual - str); + str = actual; + } + } + if (str[0] == '\\') { + ++str; + --len; + } + if (save[0] == '\\') { + ++save; + } + if (!(GC_FLAGS(str_index) & IS_STR_CONSTANT_UNQUALIFIED)) { + zend_error(E_ERROR, "Undefined constant '%s'", save); + } + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str, str); + } + if (str == str_index->val && len == str_index->len) { + ZVAL_STR(&tmp, STR_COPY(str_index)); + } else { + ZVAL_STRINGL(&tmp, str, len); + } + const_value = &tmp; + } else { +//???! + ZVAL_COPY_VALUE(&tmp, const_value); + if (Z_OPT_CONSTANT(tmp)) { + zval_update_constant_ex(&tmp, 1, NULL TSRMLS_CC); + } + zval_opt_copy_ctor(&tmp); + const_value = &tmp; + } + + if (Z_REFCOUNTED_P(element) && Z_REFCOUNT_P(element) > 1) { + ZVAL_DUP(&new_val, element); + zval_ptr_dtor(element); + ZVAL_COPY_VALUE(element, &new_val); + } + + switch (Z_TYPE_P(const_value)) { + case IS_STRING: + ret = zend_symtable_update_current_key_ex(Z_ARRVAL_P(p), Z_STR_P(const_value), HASH_UPDATE_KEY_IF_BEFORE); + break; + case IS_FALSE: + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, HASH_UPDATE_KEY_IF_BEFORE); + break; + case IS_TRUE: + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 1, HASH_UPDATE_KEY_IF_BEFORE); + break; + case IS_LONG: + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, Z_LVAL_P(const_value), HASH_UPDATE_KEY_IF_BEFORE); + break; + case IS_DOUBLE: + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, zend_dval_to_lval(Z_DVAL_P(const_value)), HASH_UPDATE_KEY_IF_BEFORE); + break; + case IS_NULL: + ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, STR_EMPTY_ALLOC(), 0, HASH_UPDATE_KEY_IF_BEFORE); + break; + default: + ret = SUCCESS; + break; + } + if (ret == SUCCESS) { + zend_hash_move_forward(Z_ARRVAL_P(p)); + } + zval_dtor(const_value); + } + zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC); + zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) { SEPARATE_ZVAL_IF_NOT_REF(p); -- cgit v1.2.1 From 0c6a6f0fba3be20010e36e127f52e58531eee32d Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 7 May 2014 15:03:56 +0400 Subject: Re-applyed Bob's patch with minor fixes --- Zend/zend_execute_API.c | 118 ------------------------------------------------ 1 file changed, 118 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 3806af0a05..15f79738e6 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -592,124 +592,6 @@ 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_ARRAY) { - zval *element, new_val; - zend_string *str_index; - ulong num_index; - int ret; - - SEPARATE_ZVAL_IF_NOT_REF(p); - - Z_TYPE_INFO_P(p) = IS_ARRAY_EX; - if (!inline_change) { - HashTable *ht = Z_ARRVAL_P(p); - ZVAL_NEW_ARR(p); - zend_hash_init(Z_ARRVAL_P(p), zend_hash_num_elements(ht), NULL, ZVAL_PTR_DTOR, 0); - zend_hash_copy(Z_ARRVAL_P(p), ht, ZVAL_COPY_CTOR); - } - - /* First go over the array and see if there are any constant indices */ - zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); - while ((element = zend_hash_get_current_data(Z_ARRVAL_P(p))) != NULL) { - if (zend_hash_get_current_key(Z_ARRVAL_P(p), &str_index, &num_index, 0) != HASH_KEY_IS_STRING) { - zend_hash_move_forward(Z_ARRVAL_P(p)); - continue; - } - if (!(GC_FLAGS(str_index) & (IS_STR_CONSTANT | IS_STR_AST))) { - zend_hash_move_forward(Z_ARRVAL_P(p)); - continue; - } - - if (GC_FLAGS(str_index) & IS_STR_AST) { - zend_ast_ref *ast = *(zend_ast_ref **)str_index->val; - - zend_ast_evaluate(&tmp, ast->ast, scope TSRMLS_CC); - zend_ast_destroy(ast->ast); - efree(ast); - const_value = &tmp; - } else if (!(const_value = zend_get_constant_ex(str_index, scope, GC_FLAGS(str_index) & ~(IS_STR_PERSISTENT | IS_STR_INTERNED |IS_STR_PERMANENT) TSRMLS_CC))) { - char *actual, *str; - const char *save = str_index->val; - int len; - - str = str_index->val; - len = str_index->len; - if ((colon = (char*)zend_memrchr(str, ':', len))) { - zend_error(E_ERROR, "Undefined class constant '%s'", str); - len -= ((colon - str) + 1); - str = colon; - } else { - if (GC_FLAGS(str_index) & IS_STR_CONSTANT_UNQUALIFIED) { - if ((actual = (char *)zend_memrchr(str, '\\', len))) { - actual++; - len -= (actual - str); - str = actual; - } - } - if (str[0] == '\\') { - ++str; - --len; - } - if (save[0] == '\\') { - ++save; - } - if (!(GC_FLAGS(str_index) & IS_STR_CONSTANT_UNQUALIFIED)) { - zend_error(E_ERROR, "Undefined constant '%s'", save); - } - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", str, str); - } - if (str == str_index->val && len == str_index->len) { - ZVAL_STR(&tmp, STR_COPY(str_index)); - } else { - ZVAL_STRINGL(&tmp, str, len); - } - const_value = &tmp; - } else { -//???! - ZVAL_COPY_VALUE(&tmp, const_value); - if (Z_OPT_CONSTANT(tmp)) { - zval_update_constant_ex(&tmp, 1, NULL TSRMLS_CC); - } - zval_opt_copy_ctor(&tmp); - const_value = &tmp; - } - - if (Z_REFCOUNTED_P(element) && Z_REFCOUNT_P(element) > 1) { - ZVAL_DUP(&new_val, element); - zval_ptr_dtor(element); - ZVAL_COPY_VALUE(element, &new_val); - } - - switch (Z_TYPE_P(const_value)) { - case IS_STRING: - ret = zend_symtable_update_current_key_ex(Z_ARRVAL_P(p), Z_STR_P(const_value), HASH_UPDATE_KEY_IF_BEFORE); - break; - case IS_FALSE: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 0, HASH_UPDATE_KEY_IF_BEFORE); - break; - case IS_TRUE: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, 1, HASH_UPDATE_KEY_IF_BEFORE); - break; - case IS_LONG: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, Z_LVAL_P(const_value), HASH_UPDATE_KEY_IF_BEFORE); - break; - case IS_DOUBLE: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_LONG, NULL, zend_dval_to_lval(Z_DVAL_P(const_value)), HASH_UPDATE_KEY_IF_BEFORE); - break; - case IS_NULL: - ret = zend_hash_update_current_key_ex(Z_ARRVAL_P(p), HASH_KEY_IS_STRING, STR_EMPTY_ALLOC(), 0, HASH_UPDATE_KEY_IF_BEFORE); - break; - default: - ret = SUCCESS; - break; - } - if (ret == SUCCESS) { - zend_hash_move_forward(Z_ARRVAL_P(p)); - } - zval_dtor(const_value); - } - zend_hash_apply_with_argument(Z_ARRVAL_P(p), (apply_func_arg_t) zval_update_constant_inline_change, (void *) scope TSRMLS_CC); - zend_hash_internal_pointer_reset(Z_ARRVAL_P(p)); } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) { SEPARATE_ZVAL_IF_NOT_REF(p); -- cgit v1.2.1 From b87cff66b871177c50317ede21cdd1c93250d28a Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sat, 24 May 2014 21:37:15 +0800 Subject: fci->retval is always set --- Zend/zend_execute_API.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 15f79738e6..9459344df6 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -857,10 +857,10 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EG(active_op_array) = (zend_op_array *) EX(function_state).function; original_opline_ptr = EG(opline_ptr); - if (EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) { - zend_generator_create_zval(EG(active_op_array), fci->retval TSRMLS_CC); - } else { + if (EXPECTED((EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) == 0)) { zend_execute(EG(active_op_array), fci->retval TSRMLS_CC); + } else { + zend_generator_create_zval(EG(active_op_array), fci->retval TSRMLS_CC); } EG(active_op_array) = original_op_array; @@ -885,9 +885,9 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS because it can break proper ones (Bug #34045) if (!EX(function_state).function->common.return_reference) { - INIT_PZVAL(*fci->retval_ptr_ptr); + INIT_PZVAL(*f); }*/ - if (EG(exception) && fci->retval) { + if (EG(exception)) { zval_ptr_dtor(fci->retval); ZVAL_UNDEF(fci->retval); } @@ -911,7 +911,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } efree(EX(function_state).function); - if (EG(exception) && fci->retval) { + if (EG(exception)) { zval_ptr_dtor(fci->retval); ZVAL_UNDEF(fci->retval); } -- cgit v1.2.1 From 00e69ba16404751728c22dbc03be8fb4bfbfbf91 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sat, 24 May 2014 21:45:07 +0800 Subject: typo --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 9459344df6..a891f97e08 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -885,7 +885,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS because it can break proper ones (Bug #34045) if (!EX(function_state).function->common.return_reference) { - INIT_PZVAL(*f); + INIT_PZVAL(f->retval); }*/ if (EG(exception)) { zval_ptr_dtor(fci->retval); -- cgit v1.2.1 From 0175d994c0f22a22c20d6b6ae04cd92355277d91 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Sun, 25 May 2014 19:56:51 +0800 Subject: Fixed apply_func_arg_t, and it's better not using cast (compiler friendly) --- Zend/zend_execute_API.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index a891f97e08..2b62f2e844 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1541,9 +1541,10 @@ typedef struct _zend_abstract_info { int ctor; } zend_abstract_info; -static int zend_verify_abstract_class_function(zval *zv, zend_abstract_info *ai TSRMLS_DC) /* {{{ */ +static int zend_verify_abstract_class_function(zval *zv, void *arg TSRMLS_DC) /* {{{ */ { - zend_function *fn = Z_PTR_P(zv); + zend_function *fn = (zend_function *)Z_PTR_P(zv); + zend_abstract_info *ai = (zend_abstract_info *)arg; if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) { if (ai->cnt < MAX_ABSTRACT_INFO_CNT) { @@ -1571,7 +1572,7 @@ void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC) /* {{{ */ if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { memset(&ai, 0, sizeof(ai)); - zend_hash_apply_with_argument(&ce->function_table, (apply_func_arg_t) zend_verify_abstract_class_function, &ai TSRMLS_CC); + zend_hash_apply_with_argument(&ce->function_table, zend_verify_abstract_class_function, &ai TSRMLS_CC); if (ai.cnt) { zend_error(E_ERROR, "Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")", -- cgit v1.2.1 From bd4b9837e9d839ea527e22d35cb7f7cf9d80d839 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Mon, 26 May 2014 17:16:22 +0800 Subject: Improve call_user_function performance params are all zval * now, and retval will be initialized in zend_call_function. maybe we can make call_user_function as a macro proxy to call_user_function_ex later. --- Zend/zend_execute_API.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 2b62f2e844..0a21e06b85 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -626,24 +626,7 @@ ZEND_API int zval_update_constant(zval *pp, zend_bool inline_change TSRMLS_DC) / int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, zend_uint param_count, zval params[] TSRMLS_DC) /* {{{ */ { - zval *params_array; - zend_uint i; - int ex_retval; - - if (param_count) { - params_array = (zval *) emalloc(sizeof(zval) * param_count); - for (i=0; i Date: Mon, 26 May 2014 17:25:57 +0800 Subject: Save some unnecessary zval copying --- Zend/zend_execute_API.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 0a21e06b85..14f6a47ab3 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -133,7 +133,6 @@ static int clean_non_persistent_class_full(zval *zv TSRMLS_DC) /* {{{ */ void init_executor(TSRMLS_D) /* {{{ */ { - zval tmp; zend_init_fpu(TSRMLS_C); ZVAL_NULL(&EG(uninitialized_zval)); @@ -157,8 +156,7 @@ void init_executor(TSRMLS_D) /* {{{ */ EG(error_handling) = EH_NORMAL; zend_vm_stack_init(TSRMLS_C); - ZVAL_LONG(&tmp, 0); - zend_vm_stack_push(&tmp TSRMLS_CC); + ZVAL_LONG(zend_vm_stack_top_inc(TSRMLS_C), 0); zend_hash_init(&EG(symbol_table).ht, 64, NULL, ZVAL_PTR_DTOR, 0); EG(active_symbol_table) = &EG(symbol_table); @@ -507,7 +505,7 @@ ZEND_API int zend_is_true(zval *op TSRMLS_DC) /* {{{ */ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_class_entry *scope TSRMLS_DC) /* {{{ */ { - zval *const_value, tmp; + zval *const_value; char *colon; if (IS_CONSTANT_VISITED(p)) { @@ -593,6 +591,7 @@ 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_IF_NOT_REF(p); zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope TSRMLS_CC); @@ -810,9 +809,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_vm_stack_push(param TSRMLS_CC); } - EX(function_state).arguments = zend_vm_stack_top(TSRMLS_C); - ZVAL_LONG(&tmp, fci->param_count); - zend_vm_stack_push(&tmp TSRMLS_CC); + EX(function_state).arguments = zend_vm_stack_top_inc(TSRMLS_C); + ZVAL_LONG(EX(function_state).arguments, fci->param_count); EG(scope) = calling_scope; EG(called_scope) = called_scope; -- cgit v1.2.1 From 40256e0f9c76b7233e264b8a6e8430feee2c551c Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 26 May 2014 17:16:16 +0400 Subject: Use specialized functions instead of macros --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 14f6a47ab3..f0f856d670 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1607,7 +1607,7 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ zval zv; ZVAL_INDIRECT(&zv, EX_VAR_NUM_2(ex, i)); - zend_hash_update(&EG(active_symbol_table)->ht, + zend_hash_add_new(&EG(active_symbol_table)->ht, ex->op_array->vars[i], &zv); } } -- cgit v1.2.1 From 411a8757ad0aa01d9634e8e32df4dd4327eb5978 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 28 May 2014 21:32:52 +0200 Subject: Initialize GC_TYPE_INFO for EG(symbol_table) --- Zend/zend_execute_API.c | 1 + 1 file changed, 1 insertion(+) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index f0f856d670..f9139aae55 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -159,6 +159,7 @@ void init_executor(TSRMLS_D) /* {{{ */ ZVAL_LONG(zend_vm_stack_top_inc(TSRMLS_C), 0); zend_hash_init(&EG(symbol_table).ht, 64, NULL, ZVAL_PTR_DTOR, 0); + GC_TYPE_INFO(&EG(symbol_table)) = IS_ARRAY; EG(active_symbol_table) = &EG(symbol_table); zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator TSRMLS_CC); -- cgit v1.2.1 From 9a9bb8877eee9e64f33e1e5a2e1d13ca015dd3d6 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 9 Jun 2014 21:29:20 +0400 Subject: Improved ZTS support --- Zend/zend_execute_API.c | 1 + 1 file changed, 1 insertion(+) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index f9139aae55..fa0ee5a9b5 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -159,6 +159,7 @@ void init_executor(TSRMLS_D) /* {{{ */ ZVAL_LONG(zend_vm_stack_top_inc(TSRMLS_C), 0); zend_hash_init(&EG(symbol_table).ht, 64, NULL, ZVAL_PTR_DTOR, 0); + GC_REFCOUNT(&EG(symbol_table)) = 1; GC_TYPE_INFO(&EG(symbol_table)) = IS_ARRAY; EG(active_symbol_table) = &EG(symbol_table); -- cgit v1.2.1 From 3c69140a9065b66259c3f114ce4528b3ec784816 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Tue, 10 Jun 2014 21:53:46 +0800 Subject: Remove unused codes --- Zend/zend_execute_API.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index fa0ee5a9b5..9a74a0d3fb 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -498,11 +498,8 @@ ZEND_API int zend_is_true(zval *op TSRMLS_DC) /* {{{ */ } /* }}} */ -#include "../TSRM/tsrm_strtok_r.h" - #define IS_VISITED_CONSTANT 0x80 #define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT) -#define Z_REAL_TYPE_P(p) (Z_TYPE_P(p) & ~IS_VISITED_CONSTANT) #define MARK_CONSTANT_VISITED(p) Z_TYPE_INFO_P(p) |= IS_VISITED_CONSTANT ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_class_entry *scope TSRMLS_DC) /* {{{ */ -- cgit v1.2.1 From e8699d75da9d3b0cc16b9454f12928defb6e72fc Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Tue, 10 Jun 2014 21:56:30 +0800 Subject: Remove unused included file --- Zend/zend_execute_API.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 45ad5c38bf..e100484f6f 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -448,8 +448,6 @@ ZEND_API int zend_is_true(zval *op) /* {{{ */ } /* }}} */ -#include "../TSRM/tsrm_strtok_r.h" - #define IS_VISITED_CONSTANT IS_CONSTANT_INDEX #define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT) #define Z_REAL_TYPE_P(p) (Z_TYPE_P(p) & ~IS_VISITED_CONSTANT) -- cgit v1.2.1 From 14e6ee7f42723c2e47bb0dd60ab0993ad3fcdd2a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 11 Jun 2014 11:39:42 +0400 Subject: Use absolute addresses as branch targets for NEW, FE_RESET and FE_FETCH --- Zend/zend_execute_API.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 9a74a0d3fb..c95986b7b0 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1192,6 +1192,9 @@ void execute_new_code(TSRMLS_D) /* {{{ */ case ZEND_JMPNZ_EX: case ZEND_JMP_SET: case ZEND_JMP_SET_VAR: + case ZEND_NEW: + case ZEND_FE_RESET: + case ZEND_FE_FETCH: opline->op2.jmp_addr = &CG(active_op_array)->opcodes[opline->op2.opline_num]; break; } -- cgit v1.2.1 From bd10db271c8ed6ca556093259c09b7d65c2257bf Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 16 Jun 2014 21:11:52 +0400 Subject: Use new zend_hash iteration API --- Zend/zend_execute_API.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index c95986b7b0..5dce62992d 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1524,11 +1524,8 @@ typedef struct _zend_abstract_info { int ctor; } zend_abstract_info; -static int zend_verify_abstract_class_function(zval *zv, void *arg TSRMLS_DC) /* {{{ */ +static void zend_verify_abstract_class_function(zend_function *fn, zend_abstract_info *ai TSRMLS_DC) /* {{{ */ { - zend_function *fn = (zend_function *)Z_PTR_P(zv); - zend_abstract_info *ai = (zend_abstract_info *)arg; - if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) { if (ai->cnt < MAX_ABSTRACT_INFO_CNT) { ai->afn[ai->cnt] = fn; @@ -1544,18 +1541,20 @@ static int zend_verify_abstract_class_function(zval *zv, void *arg TSRMLS_DC) /* ai->cnt++; } } - return 0; } /* }}} */ void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC) /* {{{ */ { + zend_function *func; zend_abstract_info ai; if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) { memset(&ai, 0, sizeof(ai)); - zend_hash_apply_with_argument(&ce->function_table, zend_verify_abstract_class_function, &ai TSRMLS_CC); + ZEND_HASH_FOREACH_PTR(&ce->function_table, func) { + zend_verify_abstract_class_function(func, &ai TSRMLS_CC); + } ZEND_HASH_FOREACH_END(); if (ai.cnt) { zend_error(E_ERROR, "Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")", -- cgit v1.2.1 From bbc508dea595ef297f2201486078b38e4b7e98fd Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 23 Jun 2014 17:01:59 +0400 Subject: Fixed string deallocation and code cleanup --- Zend/zend_execute_API.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 5dce62992d..ebb995a262 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -580,7 +580,6 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas if (inline_change) { STR_RELEASE(Z_STR_P(p)); } -//???! ZVAL_COPY_VALUE(p, const_value); if (Z_OPT_CONSTANT_P(p)) { zval_update_constant_ex(p, 1, NULL TSRMLS_CC); @@ -887,7 +886,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } if (EX(function_state).function->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) { - efree((char*)EX(function_state).function->common.function_name); + STR_RELEASE(EX(function_state).function->common.function_name); } efree(EX(function_state).function); -- cgit v1.2.1 From 43477bc7a2da3077abf290b13571f532979db57a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 24 Jun 2014 02:17:16 +0400 Subject: Refactoring: use call_frames instead of call_slots --- Zend/zend_execute_API.c | 91 ++++++++++++++++++++++++++++--------------------- 1 file changed, 52 insertions(+), 39 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index ebb995a262..d326037b15 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -393,17 +393,24 @@ void shutdown_executor(TSRMLS_D) /* {{{ */ /* return class name and "::" or "". */ ZEND_API const char *get_active_class_name(const char **space TSRMLS_DC) /* {{{ */ { + zend_function *func; + if (!zend_is_executing(TSRMLS_C)) { if (space) { *space = ""; } return ""; } - switch (EG(current_execute_data)->function_state.function->type) { + if (EG(current_execute_data)->call && (EG(current_execute_data)->call->flags & ZEND_CALL_DONE)) { + func = EG(current_execute_data)->call->func; + } else { + func = (zend_function*)EG(current_execute_data)->op_array; + } + switch (func->type) { case ZEND_USER_FUNCTION: case ZEND_INTERNAL_FUNCTION: { - zend_class_entry *ce = EG(current_execute_data)->function_state.function->common.scope; + zend_class_entry *ce = func->common.scope; if (space) { *space = ce ? "::" : ""; @@ -421,12 +428,19 @@ ZEND_API const char *get_active_class_name(const char **space TSRMLS_DC) /* {{{ ZEND_API const char *get_active_function_name(TSRMLS_D) /* {{{ */ { + zend_function *func; + if (!zend_is_executing(TSRMLS_C)) { return NULL; } - switch (EG(current_execute_data)->function_state.function->type) { + if (EG(current_execute_data)->call && (EG(current_execute_data)->call->flags & ZEND_CALL_DONE)) { + func = EG(current_execute_data)->call->func; + } else { + func = (zend_function*)EG(current_execute_data)->op_array; + } + switch (func->type) { case ZEND_USER_FUNCTION: { - zend_string *function_name = ((zend_op_array *) EG(current_execute_data)->function_state.function)->function_name; + zend_string *function_name = func->common.function_name; if (function_name) { return function_name->val; @@ -436,7 +450,7 @@ ZEND_API const char *get_active_function_name(TSRMLS_D) /* {{{ */ } break; case ZEND_INTERNAL_FUNCTION: - return ((zend_internal_function *) EG(current_execute_data)->function_state.function)->function_name->val; + return func->common.function_name->val; break; default: return NULL; @@ -655,6 +669,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_class_entry *called_scope = NULL; zend_execute_data execute_data; zend_fcall_info_cache fci_cache_local; + zend_function *func; zval tmp; ZVAL_UNDEF(fci->retval); @@ -719,7 +734,10 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS STR_RELEASE(callable_name); } - EX(function_state).function = fci_cache->function_handler; + ZEND_VM_STACK_GROW_IF_NEEDED(ZEND_CALL_FRAME_SLOT + fci->param_count); + + func = fci_cache->function_handler; + EX(call) = zend_vm_stack_push_call_frame(func, fci->param_count, ZEND_CALL_DONE, fci_cache->called_scope, fci_cache->object, NULL TSRMLS_CC); calling_scope = fci_cache->calling_scope; called_scope = fci_cache->called_scope; fci->object = fci_cache->object; @@ -729,24 +747,22 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS return FAILURE; } - if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) { - if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) { - zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", EX(function_state).function->common.scope->name->val, EX(function_state).function->common.function_name->val); + if (func->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) { + if (func->common.fn_flags & ZEND_ACC_ABSTRACT) { + zend_error_noreturn(E_ERROR, "Cannot call abstract method %s::%s()", func->common.scope->name->val, func->common.function_name->val); } - if (EX(function_state).function->common.fn_flags & ZEND_ACC_DEPRECATED) { + if (func->common.fn_flags & ZEND_ACC_DEPRECATED) { zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated", - EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name->val : "", - EX(function_state).function->common.scope ? "::" : "", - EX(function_state).function->common.function_name->val); + func->common.scope ? func->common.scope->name->val : "", + func->common.scope ? "::" : "", + func->common.function_name->val); } } - ZEND_VM_STACK_GROW_IF_NEEDED(fci->param_count + 1); - for (i=0; iparam_count; i++) { zval *param; - if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1)) { + if (ARG_SHOULD_BE_SENT_BY_REF(func, i + 1)) { // TODO: Scalar values don't have reference counters anymore. // They are assumed to be 1, and they may be easily passed by // reference now. However, previously scalars with refcount==1 @@ -766,19 +782,19 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS (!Z_ISREF(fci->params[i]) && Z_REFCOUNT(fci->params[i]) > 1)) { if (fci->no_separation && - !ARG_MAY_BE_SENT_BY_REF(EX(function_state).function, i + 1)) { + !ARG_MAY_BE_SENT_BY_REF(func, i + 1)) { if (i || UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (EG(argument_stack)->top))) { /* hack to clean up the stack */ ZVAL_LONG(&tmp, i); zend_vm_stack_push(&tmp TSRMLS_CC); - zend_vm_stack_clear_multiple(0 TSRMLS_CC); + zend_vm_stack_free_call_frame(EX(call), 0 TSRMLS_CC); } zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given", i+1, - EX(function_state).function->common.scope ? EX(function_state).function->common.scope->name->val : "", - EX(function_state).function->common.scope ? "::" : "", - EX(function_state).function->common.function_name->val); + func->common.scope ? func->common.scope->name->val : "", + func->common.scope ? "::" : "", + func->common.function_name->val); return FAILURE; } @@ -797,7 +813,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS param = &fci->params[i]; } else if (Z_ISREF(fci->params[i]) && /* don't separate references for __call */ - (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 ) { + (func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 ) { param = &tmp; ZVAL_DUP(param, Z_REFVAL(fci->params[i])); } else { @@ -807,13 +823,10 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_vm_stack_push(param TSRMLS_CC); } - EX(function_state).arguments = zend_vm_stack_top_inc(TSRMLS_C); - ZVAL_LONG(EX(function_state).arguments, fci->param_count); - EG(scope) = calling_scope; EG(called_scope) = called_scope; if (!fci->object || - (EX(function_state).function->common.fn_flags & ZEND_ACC_STATIC)) { + (func->common.fn_flags & ZEND_ACC_STATIC)) { Z_OBJ(EG(This)) = NULL; } else { Z_OBJ(EG(This)) = fci->object; @@ -823,9 +836,9 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EX(prev_execute_data) = EG(current_execute_data); EG(current_execute_data) = &execute_data; - if (EX(function_state).function->type == ZEND_USER_FUNCTION) { + if (func->type == ZEND_USER_FUNCTION) { calling_symbol_table = EG(active_symbol_table); - EG(scope) = EX(function_state).function->common.scope; + EG(scope) = func->common.scope; if (fci->symbol_table) { EG(active_symbol_table) = fci->symbol_table; } else { @@ -833,7 +846,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } original_op_array = EG(active_op_array); - EG(active_op_array) = (zend_op_array *) EX(function_state).function; + EG(active_op_array) = (zend_op_array *) func; original_opline_ptr = EG(opline_ptr); if (EXPECTED((EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) == 0)) { @@ -848,15 +861,15 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC); } EG(active_symbol_table) = calling_symbol_table; - } else if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) { - int call_via_handler = (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0; + } else if (func->type == ZEND_INTERNAL_FUNCTION) { + int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0; ZVAL_NULL(fci->retval); - if (EX(function_state).function->common.scope) { - EG(scope) = EX(function_state).function->common.scope; + if (func->common.scope) { + EG(scope) = func->common.scope; } if (EXPECTED(zend_execute_internal == NULL)) { /* saves one function call if zend_execute_internal is not used */ - EX(function_state).function->internal_function.handler(fci->param_count, fci->retval TSRMLS_CC); + func->internal_function.handler(fci->param_count, fci->retval TSRMLS_CC); } else { zend_execute_internal(&execute_data, fci TSRMLS_CC); } @@ -880,22 +893,22 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS /* Not sure what should be done here if it's a static method */ if (fci->object) { - fci->object->handlers->call_method(EX(function_state).function->common.function_name, fci->object, fci->param_count, fci->retval TSRMLS_CC); + fci->object->handlers->call_method(func->common.function_name, fci->object, fci->param_count, fci->retval TSRMLS_CC); } else { zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object"); } - if (EX(function_state).function->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) { - STR_RELEASE(EX(function_state).function->common.function_name); + if (func->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) { + STR_RELEASE(func->common.function_name); } - efree(EX(function_state).function); + efree(func); if (EG(exception)) { zval_ptr_dtor(fci->retval); ZVAL_UNDEF(fci->retval); } } - zend_vm_stack_clear_multiple(0 TSRMLS_CC); + zend_vm_stack_free_call_frame(EX(call), 0 TSRMLS_CC); if (Z_OBJ(EG(This))) { zval_ptr_dtor(&EG(This)); -- cgit v1.2.1 From c69781393cd42db7479d24f39e0f55f1b7f1d355 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 26 Jun 2014 23:51:14 +0400 Subject: Refactoring: merge call_frame and end_execute_data into single data structure. Keep only single copy of each argument on VM stack (previously ZE kept two copies of each arguments for user functions) --- Zend/zend_execute_API.c | 88 +++++++++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 40 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index d326037b15..1efed55eb3 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -156,7 +156,6 @@ void init_executor(TSRMLS_D) /* {{{ */ EG(error_handling) = EH_NORMAL; zend_vm_stack_init(TSRMLS_C); - ZVAL_LONG(zend_vm_stack_top_inc(TSRMLS_C), 0); zend_hash_init(&EG(symbol_table).ht, 64, NULL, ZVAL_PTR_DTOR, 0); GC_REFCOUNT(&EG(symbol_table)) = 1; @@ -401,10 +400,11 @@ ZEND_API const char *get_active_class_name(const char **space TSRMLS_DC) /* {{{ } return ""; } + if (EG(current_execute_data)->call && (EG(current_execute_data)->call->flags & ZEND_CALL_DONE)) { func = EG(current_execute_data)->call->func; } else { - func = (zend_function*)EG(current_execute_data)->op_array; + func = EG(current_execute_data)->func; } switch (func->type) { case ZEND_USER_FUNCTION: @@ -436,7 +436,7 @@ ZEND_API const char *get_active_function_name(TSRMLS_D) /* {{{ */ if (EG(current_execute_data)->call && (EG(current_execute_data)->call->flags & ZEND_CALL_DONE)) { func = EG(current_execute_data)->call->func; } else { - func = (zend_function*)EG(current_execute_data)->op_array; + func = EG(current_execute_data)->func; } switch (func->type) { case ZEND_USER_FUNCTION: { @@ -696,7 +696,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EX(object) = Z_OBJ(EG(This)); EX(scope) = EG(scope); EX(called_scope) = EG(called_scope); - EX(op_array) = NULL; + EX(func) = NULL; EX(opline) = NULL; } else { /* This only happens when we're called outside any execute()'s @@ -734,8 +734,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS STR_RELEASE(callable_name); } - ZEND_VM_STACK_GROW_IF_NEEDED(ZEND_CALL_FRAME_SLOT + fci->param_count); - func = fci_cache->function_handler; EX(call) = zend_vm_stack_push_call_frame(func, fci->param_count, ZEND_CALL_DONE, fci_cache->called_scope, fci_cache->object, NULL TSRMLS_CC); calling_scope = fci_cache->calling_scope; @@ -783,12 +781,12 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS if (fci->no_separation && !ARG_MAY_BE_SENT_BY_REF(func, i + 1)) { - if (i || UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (EG(argument_stack)->top))) { + if (i) { /* hack to clean up the stack */ - ZVAL_LONG(&tmp, i); - zend_vm_stack_push(&tmp TSRMLS_CC); - zend_vm_stack_free_call_frame(EX(call), 0 TSRMLS_CC); + EX(call)->num_args = i; + zend_vm_stack_free_args(EX(call) TSRMLS_CC); } + zend_vm_stack_free_call_frame(EX(call) TSRMLS_CC); zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given", i+1, @@ -810,24 +808,26 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } else if (Z_REFCOUNTED(fci->params[i])) { Z_ADDREF(fci->params[i]); } - param = &fci->params[i]; + param = ZEND_CALL_ARG(EX(call), i+1); + ZVAL_COPY_VALUE(param, &fci->params[i]); } else if (Z_ISREF(fci->params[i]) && /* don't separate references for __call */ (func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 ) { param = &tmp; + param = ZEND_CALL_ARG(EX(call), i+1); ZVAL_DUP(param, Z_REFVAL(fci->params[i])); } else { - param = &tmp; + param = ZEND_CALL_ARG(EX(call), i+1); ZVAL_COPY(param, &fci->params[i]); } - zend_vm_stack_push(param TSRMLS_CC); } + EX(call)->num_args = fci->param_count; EG(scope) = calling_scope; EG(called_scope) = called_scope; if (!fci->object || (func->common.fn_flags & ZEND_ACC_STATIC)) { - Z_OBJ(EG(This)) = NULL; + Z_OBJ(EG(This)) = EX(call)->object = NULL; } else { Z_OBJ(EG(This)) = fci->object; Z_ADDREF(EG(This)); @@ -873,6 +873,9 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } else { zend_execute_internal(&execute_data, fci TSRMLS_CC); } + zend_vm_stack_free_args(EX(call) TSRMLS_CC); + zend_vm_stack_free_call_frame(EX(call) TSRMLS_CC); + /* We shouldn't fix bad extensions here, because it can break proper ones (Bug #34045) if (!EX(function_state).function->common.return_reference) @@ -908,7 +911,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS ZVAL_UNDEF(fci->retval); } } - zend_vm_stack_free_call_frame(EX(call), 0 TSRMLS_CC); +//??? zend_vm_stack_free_call_frame(EX(call), 0 TSRMLS_CC); if (Z_OBJ(EG(This))) { zval_ptr_dtor(&EG(This)); @@ -1093,6 +1096,10 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s zend_try { ZVAL_UNDEF(&local_retval); + if (EG(current_execute_data)) { + EG(current_execute_data)->call = zend_vm_stack_push_call_frame( + (zend_function*)new_op_array, 0, 0, EG(called_scope), Z_OBJ(EG(This)), EG(current_execute_data)->call TSRMLS_CC); + } zend_execute(new_op_array, &local_retval TSRMLS_CC); } zend_catch { destroy_op_array(new_op_array TSRMLS_CC); @@ -1596,33 +1603,34 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ /* Search for last called user function */ ex = EG(current_execute_data); - while (ex && !ex->op_array) { + while (ex && (!ex->func || (ex->func->common.type != ZEND_USER_FUNCTION && ex->func->common.type != ZEND_EVAL_CODE))) { ex = ex->prev_execute_data; } - if (ex && ex->symbol_table) { + if (!ex) { + return; + } + if (ex->symbol_table) { EG(active_symbol_table) = ex->symbol_table; return; } - if (ex && ex->op_array) { - if (EG(symtable_cache_ptr)>=EG(symtable_cache)) { - /*printf("Cache hit! Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/ - EG(active_symbol_table) = *(EG(symtable_cache_ptr)--); - } else { - EG(active_symbol_table) = emalloc(sizeof(zend_array)); - GC_REFCOUNT(EG(active_symbol_table)) = 0; - GC_TYPE_INFO(EG(active_symbol_table)) = IS_ARRAY; - zend_hash_init(&EG(active_symbol_table)->ht, ex->op_array->last_var, NULL, ZVAL_PTR_DTOR, 0); - /*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/ - } - ex->symbol_table = EG(active_symbol_table); - for (i = 0; i < ex->op_array->last_var; i++) { - zval zv; - - ZVAL_INDIRECT(&zv, EX_VAR_NUM_2(ex, i)); - zend_hash_add_new(&EG(active_symbol_table)->ht, - ex->op_array->vars[i], &zv); - } + if (EG(symtable_cache_ptr)>=EG(symtable_cache)) { + /*printf("Cache hit! Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/ + EG(active_symbol_table) = *(EG(symtable_cache_ptr)--); + } else { + EG(active_symbol_table) = emalloc(sizeof(zend_array)); + GC_REFCOUNT(EG(active_symbol_table)) = 0; + GC_TYPE_INFO(EG(active_symbol_table)) = IS_ARRAY; + zend_hash_init(&EG(active_symbol_table)->ht, ex->func->op_array.last_var, NULL, ZVAL_PTR_DTOR, 0); + /*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/ + } + ex->symbol_table = EG(active_symbol_table); + for (i = 0; i < ex->func->op_array.last_var; i++) { + zval zv; + + ZVAL_INDIRECT(&zv, EX_VAR_NUM_2(ex, i)); + zend_hash_add_new(&EG(active_symbol_table)->ht, + ex->func->op_array.vars[i], &zv); } } } @@ -1631,7 +1639,7 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data) /* {{{ */ { int i; - zend_op_array *op_array = execute_data->op_array; + zend_op_array *op_array = &execute_data->func->op_array; HashTable *ht = &execute_data->symbol_table->ht; /* copy real values from symbol table into CV slots and create @@ -1662,7 +1670,7 @@ ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data) /* {{{ * ZEND_API void zend_detach_symbol_table(zend_execute_data *execute_data) /* {{{ */ { int i; - zend_op_array *op_array = execute_data->op_array; + zend_op_array *op_array = &execute_data->func->op_array; HashTable *ht = &execute_data->symbol_table->ht; /* copy real values from CV slots into symbol table */ @@ -1682,7 +1690,7 @@ ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force TSRMLS if (!EG(active_symbol_table)) { int i; zend_execute_data *execute_data = EG(current_execute_data); - zend_op_array *op_array = execute_data->op_array; + zend_op_array *op_array = &execute_data->func->op_array; zend_ulong h = STR_HASH_VAL(name); if (op_array) { @@ -1715,7 +1723,7 @@ ZEND_API int zend_set_local_var_str(const char *name, int len, zval *value, int if (!EG(active_symbol_table)) { int i; zend_execute_data *execute_data = EG(current_execute_data); - zend_op_array *op_array = execute_data->op_array; + zend_op_array *op_array = &execute_data->func->op_array; zend_ulong h = zend_hash_func(name, len); if (op_array) { -- cgit v1.2.1 From 032f33591a643c0cabe615a016b8f79f2fd9b277 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 27 Jun 2014 12:25:36 +0400 Subject: Keep extra args in the same VM stack segment (after all CV and TMP vars) --- Zend/zend_execute_API.c | 1 - 1 file changed, 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 1efed55eb3..92e0ede804 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -911,7 +911,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS ZVAL_UNDEF(fci->retval); } } -//??? zend_vm_stack_free_call_frame(EX(call), 0 TSRMLS_CC); if (Z_OBJ(EG(This))) { zval_ptr_dtor(&EG(This)); -- cgit v1.2.1 From d6bd21eab2ad5beaab248851e3a5cef9cdb24b5c Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 27 Jun 2014 13:02:49 +0400 Subject: Use fast comparison for (func->type == ZEND_USER_FUNCTION || func->type == ZEND_EVAL_CODE) --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 92e0ede804..2ba582942a 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1602,7 +1602,7 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ /* Search for last called user function */ ex = EG(current_execute_data); - while (ex && (!ex->func || (ex->func->common.type != ZEND_USER_FUNCTION && ex->func->common.type != ZEND_EVAL_CODE))) { + while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->common.type))) { ex = ex->prev_execute_data; } if (!ex) { -- cgit v1.2.1 From 412ad4b25417d261c0a8c43f788d5c110593d891 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 2 Jul 2014 22:01:25 +0400 Subject: Uinified call frame handling for user and internal functions. Now EG(current_execute_data) always point to the call frame of the currently executed function. --- Zend/zend_execute_API.c | 122 +++++++++++++++++++++++++++++++----------------- 1 file changed, 80 insertions(+), 42 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 2ba582942a..e91812d195 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -401,11 +401,7 @@ ZEND_API const char *get_active_class_name(const char **space TSRMLS_DC) /* {{{ return ""; } - if (EG(current_execute_data)->call && (EG(current_execute_data)->call->flags & ZEND_CALL_DONE)) { - func = EG(current_execute_data)->call->func; - } else { - func = EG(current_execute_data)->func; - } + func = EG(current_execute_data)->func; switch (func->type) { case ZEND_USER_FUNCTION: case ZEND_INTERNAL_FUNCTION: @@ -433,11 +429,7 @@ ZEND_API const char *get_active_function_name(TSRMLS_D) /* {{{ */ if (!zend_is_executing(TSRMLS_C)) { return NULL; } - if (EG(current_execute_data)->call && (EG(current_execute_data)->call->flags & ZEND_CALL_DONE)) { - func = EG(current_execute_data)->call->func; - } else { - func = EG(current_execute_data)->func; - } + func = EG(current_execute_data)->func; switch (func->type) { case ZEND_USER_FUNCTION: { zend_string *function_name = func->common.function_name; @@ -667,9 +659,11 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_op **original_opline_ptr; zend_class_entry *calling_scope = NULL; zend_class_entry *called_scope = NULL; - zend_execute_data execute_data; + zend_execute_data *call, dummy_execute_data; zend_fcall_info_cache fci_cache_local; zend_function *func; + zend_object *orig_object; + zend_class_entry *orig_scope, *orig_called_scope; zval tmp; ZVAL_UNDEF(fci->retval); @@ -690,20 +684,28 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS break; } + orig_object = Z_OBJ(EG(This)); + orig_scope = EG(scope); + orig_called_scope = EG(called_scope); + /* Initialize execute_data */ - if (EG(current_execute_data)) { - execute_data = *EG(current_execute_data); - EX(object) = Z_OBJ(EG(This)); - EX(scope) = EG(scope); - EX(called_scope) = EG(called_scope); - EX(func) = NULL; - EX(opline) = NULL; - } else { + if (!EG(current_execute_data)) { /* This only happens when we're called outside any execute()'s * It shouldn't be strictly necessary to NULL execute_data out, * but it may make bugs easier to spot */ - memset(&execute_data, 0, sizeof(zend_execute_data)); + memset(&dummy_execute_data, 0, sizeof(zend_execute_data)); + EG(current_execute_data) = &dummy_execute_data; + } else if (EG(current_execute_data)->opline && + EG(current_execute_data)->opline->opcode != ZEND_DO_FCALL) { + /* 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); + dummy_execute_data.call = NULL; + dummy_execute_data.prev_nested_call = NULL; + dummy_execute_data.opline = NULL; + dummy_execute_data.func = NULL; + EG(current_execute_data) = &dummy_execute_data; } if (!fci_cache || !fci_cache->initialized) { @@ -722,6 +724,9 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS if (callable_name) { STR_RELEASE(callable_name); } + if (EG(current_execute_data) == &dummy_execute_data) { + EG(current_execute_data) = dummy_execute_data.prev_execute_data; + } return FAILURE; } else if (error) { /* Capitalize the first latter of the error message */ @@ -735,13 +740,16 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } func = fci_cache->function_handler; - EX(call) = zend_vm_stack_push_call_frame(func, fci->param_count, ZEND_CALL_DONE, fci_cache->called_scope, fci_cache->object, NULL TSRMLS_CC); + call = zend_vm_stack_push_call_frame(func, fci->param_count, ZEND_CALL_DONE, fci_cache->called_scope, fci_cache->object, NULL TSRMLS_CC); calling_scope = fci_cache->calling_scope; called_scope = fci_cache->called_scope; fci->object = fci_cache->object; if (fci->object && (!EG(objects_store).object_buckets || !IS_OBJ_VALID(EG(objects_store).object_buckets[fci->object->handle]))) { + if (EG(current_execute_data) == &dummy_execute_data) { + EG(current_execute_data) = dummy_execute_data.prev_execute_data; + } return FAILURE; } @@ -783,16 +791,19 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS !ARG_MAY_BE_SENT_BY_REF(func, i + 1)) { if (i) { /* hack to clean up the stack */ - EX(call)->num_args = i; - zend_vm_stack_free_args(EX(call) TSRMLS_CC); + call->num_args = i; + zend_vm_stack_free_args(call TSRMLS_CC); } - zend_vm_stack_free_call_frame(EX(call) TSRMLS_CC); + zend_vm_stack_free_call_frame(call TSRMLS_CC); zend_error(E_WARNING, "Parameter %d to %s%s%s() expected to be a reference, value given", i+1, func->common.scope ? func->common.scope->name->val : "", func->common.scope ? "::" : "", func->common.function_name->val); + if (EG(current_execute_data) == &dummy_execute_data) { + EG(current_execute_data) = dummy_execute_data.prev_execute_data; + } return FAILURE; } @@ -808,33 +819,33 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } else if (Z_REFCOUNTED(fci->params[i])) { Z_ADDREF(fci->params[i]); } - param = ZEND_CALL_ARG(EX(call), i+1); + param = ZEND_CALL_ARG(call, i+1); ZVAL_COPY_VALUE(param, &fci->params[i]); } else if (Z_ISREF(fci->params[i]) && /* don't separate references for __call */ (func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 ) { param = &tmp; - param = ZEND_CALL_ARG(EX(call), i+1); + param = ZEND_CALL_ARG(call, i+1); ZVAL_DUP(param, Z_REFVAL(fci->params[i])); } else { - param = ZEND_CALL_ARG(EX(call), i+1); + param = ZEND_CALL_ARG(call, i+1); ZVAL_COPY(param, &fci->params[i]); } } - EX(call)->num_args = fci->param_count; + call->num_args = fci->param_count; EG(scope) = calling_scope; EG(called_scope) = called_scope; if (!fci->object || (func->common.fn_flags & ZEND_ACC_STATIC)) { - Z_OBJ(EG(This)) = EX(call)->object = NULL; + Z_OBJ(EG(This)) = call->object = NULL; } else { Z_OBJ(EG(This)) = fci->object; Z_ADDREF(EG(This)); } - EX(prev_execute_data) = EG(current_execute_data); - EG(current_execute_data) = &execute_data; + call->prev_nested_call = EG(current_execute_data)->call; + EG(current_execute_data)->call = call; if (func->type == ZEND_USER_FUNCTION) { calling_symbol_table = EG(active_symbol_table); @@ -867,14 +878,20 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS if (func->common.scope) { EG(scope) = func->common.scope; } + call->opline = NULL; + call->call = NULL; + call->prev_execute_data = EG(current_execute_data); + EG(current_execute_data) = call; if (EXPECTED(zend_execute_internal == NULL)) { /* saves one function call if zend_execute_internal is not used */ func->internal_function.handler(fci->param_count, fci->retval TSRMLS_CC); } else { - zend_execute_internal(&execute_data, fci TSRMLS_CC); + zend_execute_internal(call->prev_execute_data, fci TSRMLS_CC); } - zend_vm_stack_free_args(EX(call) TSRMLS_CC); - zend_vm_stack_free_call_frame(EX(call) TSRMLS_CC); + EG(current_execute_data) = call->prev_execute_data; + zend_vm_stack_free_args(call TSRMLS_CC); + EG(current_execute_data)->call = call->prev_nested_call; + zend_vm_stack_free_call_frame(call TSRMLS_CC); /* We shouldn't fix bad extensions here, because it can break proper ones (Bug #34045) @@ -896,11 +913,20 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS /* Not sure what should be done here if it's a static method */ if (fci->object) { + call->opline = NULL; + call->call = NULL; + call->prev_execute_data = EG(current_execute_data); + EG(current_execute_data) = call; fci->object->handlers->call_method(func->common.function_name, fci->object, fci->param_count, fci->retval TSRMLS_CC); + EG(current_execute_data) = call->prev_execute_data; } else { zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object"); } + zend_vm_stack_free_args(call TSRMLS_CC); + EG(current_execute_data)->call = call->prev_nested_call; + zend_vm_stack_free_call_frame(call TSRMLS_CC); + if (func->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) { STR_RELEASE(func->common.function_name); } @@ -916,10 +942,12 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zval_ptr_dtor(&EG(This)); } - Z_OBJ(EG(This)) = EX(object); - EG(scope) = EX(scope); - EG(called_scope) = EX(called_scope); - EG(current_execute_data) = EX(prev_execute_data); + Z_OBJ(EG(This)) = orig_object; + EG(scope) = orig_scope; + EG(called_scope) = orig_called_scope; + if (EG(current_execute_data) == &dummy_execute_data) { + EG(current_execute_data) = dummy_execute_data.prev_execute_data; + } if (EG(exception)) { zend_throw_exception_internal(NULL TSRMLS_CC); @@ -1689,10 +1717,15 @@ ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force TSRMLS if (!EG(active_symbol_table)) { int i; zend_execute_data *execute_data = EG(current_execute_data); - zend_op_array *op_array = &execute_data->func->op_array; + zend_op_array *op_array; zend_ulong h = STR_HASH_VAL(name); - if (op_array) { + while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) { + execute_data = execute_data->prev_execute_data; + } + + if (execute_data && execute_data->func) { + op_array = &execute_data->func->op_array; for (i = 0; i < op_array->last_var; i++) { if (op_array->vars[i]->h == h && op_array->vars[i]->len == name->len && @@ -1722,10 +1755,15 @@ ZEND_API int zend_set_local_var_str(const char *name, int len, zval *value, int if (!EG(active_symbol_table)) { int i; zend_execute_data *execute_data = EG(current_execute_data); - zend_op_array *op_array = &execute_data->func->op_array; + zend_op_array *op_array; zend_ulong h = zend_hash_func(name, len); - if (op_array) { + while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) { + execute_data = execute_data->prev_execute_data; + } + + if (execute_data && execute_data->func) { + op_array = &execute_data->func->op_array; for (i = 0; i < op_array->last_var; i++) { if (op_array->vars[i]->h == h && op_array->vars[i]->len == len && -- cgit v1.2.1 From 4b09dd69e6bd31f4010bf48e9e07e63cb5f3c2a4 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 2 Jul 2014 22:03:21 +0400 Subject: Removed EG(active_op_array) and use corresponding value from EG(current_execute_data) --- Zend/zend_execute_API.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index e91812d195..dfd82b25b4 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -192,8 +192,6 @@ void init_executor(TSRMLS_D) /* {{{ */ ZVAL_OBJ(&EG(This), NULL); - EG(active_op_array) = NULL; - EG(active) = 1; EG(start_op) = NULL; } @@ -452,8 +450,13 @@ ZEND_API const char *get_active_function_name(TSRMLS_D) /* {{{ */ ZEND_API const char *zend_get_executed_filename(TSRMLS_D) /* {{{ */ { - if (EG(active_op_array)) { - return EG(active_op_array)->filename->val; + zend_execute_data *ex = EG(current_execute_data); + + while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) { + ex = ex->prev_execute_data; + } + if (ex) { + return ex->func->op_array.filename->val; } else { return "[no active file]"; } @@ -462,12 +465,17 @@ ZEND_API const char *zend_get_executed_filename(TSRMLS_D) /* {{{ */ ZEND_API uint zend_get_executed_lineno(TSRMLS_D) /* {{{ */ { - if(EG(exception) && EG(opline_ptr) && active_opline->opcode == ZEND_HANDLE_EXCEPTION && - active_opline->lineno == 0 && EG(opline_before_exception)) { - return EG(opline_before_exception)->lineno; + zend_execute_data *ex = EG(current_execute_data); + + while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) { + ex = ex->prev_execute_data; } - if (EG(opline_ptr)) { - return active_opline->lineno; + if (ex && ex->opline) { + if (EG(exception) && ex->opline->opcode == ZEND_HANDLE_EXCEPTION && + ex->opline->lineno == 0 && EG(opline_before_exception)) { + return EG(opline_before_exception)->lineno; + } + return ex->opline->lineno; } else { return 0; } @@ -655,7 +663,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS { zend_uint i; zend_array *calling_symbol_table; - zend_op_array *original_op_array; zend_op **original_opline_ptr; zend_class_entry *calling_scope = NULL; zend_class_entry *called_scope = NULL; @@ -856,17 +863,14 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EG(active_symbol_table) = NULL; } - original_op_array = EG(active_op_array); - EG(active_op_array) = (zend_op_array *) func; original_opline_ptr = EG(opline_ptr); - if (EXPECTED((EG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) == 0)) { - zend_execute(EG(active_op_array), fci->retval TSRMLS_CC); + if (EXPECTED((func->op_array.fn_flags & ZEND_ACC_GENERATOR) == 0)) { + zend_execute(&func->op_array, fci->retval TSRMLS_CC); } else { - zend_generator_create_zval(EG(active_op_array), fci->retval TSRMLS_CC); + zend_generator_create_zval(&func->op_array, fci->retval TSRMLS_CC); } - EG(active_op_array) = original_op_array; EG(opline_ptr) = original_opline_ptr; if (!fci->symbol_table && EG(active_symbol_table)) { zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC); @@ -1088,7 +1092,6 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s { zval pv; zend_op_array *new_op_array; - zend_op_array *original_active_op_array = EG(active_op_array); zend_uint original_compiler_options; int retval; @@ -1114,7 +1117,6 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s zend_op **original_opline_ptr = EG(opline_ptr); int orig_interactive = CG(interactive); - EG(active_op_array) = new_op_array; EG(no_extensions)=1; if (!EG(active_symbol_table)) { zend_rebuild_symbol_table(TSRMLS_C); @@ -1149,7 +1151,6 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s EG(no_extensions)=0; EG(opline_ptr) = original_opline_ptr; - EG(active_op_array) = original_active_op_array; destroy_op_array(new_op_array TSRMLS_CC); efree(new_op_array); retval = SUCCESS; @@ -1250,7 +1251,6 @@ void execute_new_code(TSRMLS_D) /* {{{ */ zend_release_labels(1 TSRMLS_CC); - EG(active_op_array) = CG(active_op_array); orig_interactive = CG(interactive); CG(interactive) = 0; zend_execute(CG(active_op_array), NULL TSRMLS_CC); -- cgit v1.2.1 From 63c057e3313918a800ad7faebdb648216ddba4c0 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 2 Jul 2014 23:29:53 +0400 Subject: Removed EG(opline_ptr) and use corresponding value from EG(current_execute_data) --- Zend/zend_execute_API.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index dfd82b25b4..7e66b64d98 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -163,7 +163,6 @@ void init_executor(TSRMLS_D) /* {{{ */ EG(active_symbol_table) = &EG(symbol_table); zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator TSRMLS_CC); - EG(opline_ptr) = NULL; zend_hash_init(&EG(included_files), 8, NULL, NULL, 0); @@ -663,7 +662,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS { zend_uint i; zend_array *calling_symbol_table; - zend_op **original_opline_ptr; zend_class_entry *calling_scope = NULL; zend_class_entry *called_scope = NULL; zend_execute_data *call, dummy_execute_data; @@ -863,15 +861,12 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EG(active_symbol_table) = NULL; } - original_opline_ptr = EG(opline_ptr); - if (EXPECTED((func->op_array.fn_flags & ZEND_ACC_GENERATOR) == 0)) { zend_execute(&func->op_array, fci->retval TSRMLS_CC); } else { zend_generator_create_zval(&func->op_array, fci->retval TSRMLS_CC); } - EG(opline_ptr) = original_opline_ptr; if (!fci->symbol_table && EG(active_symbol_table)) { zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC); } @@ -1114,7 +1109,6 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s if (new_op_array) { zval local_retval; - zend_op **original_opline_ptr = EG(opline_ptr); int orig_interactive = CG(interactive); EG(no_extensions)=1; @@ -1150,7 +1144,6 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s } EG(no_extensions)=0; - EG(opline_ptr) = original_opline_ptr; destroy_op_array(new_op_array TSRMLS_CC); efree(new_op_array); retval = SUCCESS; -- cgit v1.2.1 From 0a77dcd4b9046adb7c8f719ded19c5eff0c8976a Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 3 Jul 2014 01:02:25 +0400 Subject: Removed EG(in_execution). If EG(currentent_execute_data) is not NULL we are executing something. --- Zend/zend_execute_API.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 7e66b64d98..dc23ff85e0 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -150,7 +150,6 @@ void init_executor(TSRMLS_D) /* {{{ */ EG(function_table) = CG(function_table); EG(class_table) = CG(class_table); - EG(in_execution) = 0; EG(in_autoload) = NULL; EG(autoload_func) = NULL; EG(error_handling) = EH_NORMAL; @@ -483,7 +482,7 @@ ZEND_API uint zend_get_executed_lineno(TSRMLS_D) /* {{{ */ ZEND_API zend_bool zend_is_executing(TSRMLS_D) /* {{{ */ { - return EG(in_execution); + return EG(current_execute_data) != 0; } /* }}} */ -- cgit v1.2.1 From c4d99ec982e214d05b398694dc76a9caac16fbd1 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 3 Jul 2014 02:34:43 +0400 Subject: Removed EG(called_scope) and use corresponding value from EG(current_execute_data) --- Zend/zend_execute_API.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index dc23ff85e0..d5bc4c5cf0 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -186,7 +186,6 @@ void init_executor(TSRMLS_D) /* {{{ */ EG(prev_exception) = NULL; EG(scope) = NULL; - EG(called_scope) = NULL; ZVAL_OBJ(&EG(This), NULL); @@ -662,12 +661,11 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_uint i; zend_array *calling_symbol_table; zend_class_entry *calling_scope = NULL; - zend_class_entry *called_scope = NULL; zend_execute_data *call, dummy_execute_data; zend_fcall_info_cache fci_cache_local; zend_function *func; zend_object *orig_object; - zend_class_entry *orig_scope, *orig_called_scope; + zend_class_entry *orig_scope; zval tmp; ZVAL_UNDEF(fci->retval); @@ -690,7 +688,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS orig_object = Z_OBJ(EG(This)); orig_scope = EG(scope); - orig_called_scope = EG(called_scope); /* Initialize execute_data */ if (!EG(current_execute_data)) { @@ -746,7 +743,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS func = fci_cache->function_handler; call = zend_vm_stack_push_call_frame(func, fci->param_count, ZEND_CALL_DONE, fci_cache->called_scope, fci_cache->object, NULL TSRMLS_CC); calling_scope = fci_cache->calling_scope; - called_scope = fci_cache->called_scope; fci->object = fci_cache->object; if (fci->object && (!EG(objects_store).object_buckets || @@ -839,7 +835,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS call->num_args = fci->param_count; EG(scope) = calling_scope; - EG(called_scope) = called_scope; if (!fci->object || (func->common.fn_flags & ZEND_ACC_STATIC)) { Z_OBJ(EG(This)) = call->object = NULL; @@ -942,7 +937,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS Z_OBJ(EG(This)) = orig_object; EG(scope) = orig_scope; - EG(called_scope) = orig_called_scope; if (EG(current_execute_data) == &dummy_execute_data) { EG(current_execute_data) = dummy_execute_data.prev_execute_data; } @@ -1120,7 +1114,7 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s ZVAL_UNDEF(&local_retval); if (EG(current_execute_data)) { EG(current_execute_data)->call = zend_vm_stack_push_call_frame( - (zend_function*)new_op_array, 0, 0, EG(called_scope), Z_OBJ(EG(This)), EG(current_execute_data)->call TSRMLS_CC); + (zend_function*)new_op_array, 0, 0, EG(current_execute_data)->called_scope, Z_OBJ(EG(This)), EG(current_execute_data)->call TSRMLS_CC); } zend_execute(new_op_array, &local_retval TSRMLS_CC); } zend_catch { @@ -1494,10 +1488,10 @@ check_fetch_type: } return EG(scope)->parent; case ZEND_FETCH_CLASS_STATIC: - if (!EG(called_scope)) { + if (!EG(current_execute_data) || !EG(current_execute_data)->called_scope) { zend_error(E_ERROR, "Cannot access static:: when no class scope is active"); } - return EG(called_scope); + return EG(current_execute_data)->called_scope; case ZEND_FETCH_CLASS_AUTO: { fetch_type = zend_get_class_fetch_type(class_name->val, class_name->len); if (fetch_type!=ZEND_FETCH_CLASS_DEFAULT) { -- cgit v1.2.1 From 6bf24f4dd01331122a0f10db392c08605f159826 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 4 Jul 2014 18:03:45 +0400 Subject: Removed EG(active_symbol_table) and use corresponding value from EG(current_execute_data) --- Zend/zend_execute_API.c | 161 +++++++++++++++++++++--------------------------- 1 file changed, 71 insertions(+), 90 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index d5bc4c5cf0..6730bacf40 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -159,7 +159,7 @@ void init_executor(TSRMLS_D) /* {{{ */ zend_hash_init(&EG(symbol_table).ht, 64, NULL, ZVAL_PTR_DTOR, 0); GC_REFCOUNT(&EG(symbol_table)) = 1; GC_TYPE_INFO(&EG(symbol_table)) = IS_ARRAY; - EG(active_symbol_table) = &EG(symbol_table); + EG(valid_symbol_table) = 1; zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator TSRMLS_CC); @@ -266,6 +266,7 @@ void shutdown_executor(TSRMLS_D) /* {{{ */ } zend_hash_graceful_reverse_destroy(&EG(symbol_table).ht); } zend_end_try(); + EG(valid_symbol_table) = 0; zend_try { zval *zeh; @@ -659,7 +660,6 @@ int call_user_function_ex(HashTable *function_table, zval *object, zval *functio int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TSRMLS_DC) /* {{{ */ { zend_uint i; - zend_array *calling_symbol_table; zend_class_entry *calling_scope = NULL; zend_execute_data *call, dummy_execute_data; zend_fcall_info_cache fci_cache_local; @@ -847,24 +847,13 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EG(current_execute_data)->call = call; if (func->type == ZEND_USER_FUNCTION) { - calling_symbol_table = EG(active_symbol_table); EG(scope) = func->common.scope; - if (fci->symbol_table) { - EG(active_symbol_table) = fci->symbol_table; - } else { - EG(active_symbol_table) = NULL; - } - + call->symbol_table = fci->symbol_table; if (EXPECTED((func->op_array.fn_flags & ZEND_ACC_GENERATOR) == 0)) { zend_execute(&func->op_array, fci->retval TSRMLS_CC); } else { zend_generator_create_zval(&func->op_array, fci->retval TSRMLS_CC); } - - if (!fci->symbol_table && EG(active_symbol_table)) { - zend_clean_and_cache_symbol_table(EG(active_symbol_table) TSRMLS_CC); - } - EG(active_symbol_table) = calling_symbol_table; } else if (func->type == ZEND_INTERNAL_FUNCTION) { int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0; ZVAL_NULL(fci->retval); @@ -1104,10 +1093,7 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s zval local_retval; int orig_interactive = CG(interactive); - EG(no_extensions)=1; - if (!EG(active_symbol_table)) { - zend_rebuild_symbol_table(TSRMLS_C); - } + EG(no_extensions)=1; CG(interactive) = 0; zend_try { @@ -1115,6 +1101,7 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s if (EG(current_execute_data)) { EG(current_execute_data)->call = zend_vm_stack_push_call_frame( (zend_function*)new_op_array, 0, 0, EG(current_execute_data)->called_scope, Z_OBJ(EG(This)), EG(current_execute_data)->call TSRMLS_CC); + EG(current_execute_data)->call->symbol_table = zend_rebuild_symbol_table(TSRMLS_C); } zend_execute(new_op_array, &local_retval TSRMLS_CC); } zend_catch { @@ -1607,45 +1594,42 @@ ZEND_API int zend_delete_global_variable(zend_string *name TSRMLS_DC) /* {{{ */ } /* }}} */ -ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ +ZEND_API zend_array *zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ { zend_uint i; zend_execute_data *ex; + zend_array *symbol_table; - if (!EG(active_symbol_table)) { - - /* Search for last called user function */ - ex = EG(current_execute_data); - while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->common.type))) { - ex = ex->prev_execute_data; - } - if (!ex) { - return; - } - if (ex->symbol_table) { - EG(active_symbol_table) = ex->symbol_table; - return; - } + /* Search for last called user function */ + ex = EG(current_execute_data); + while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->common.type))) { + ex = ex->prev_execute_data; + } + if (!ex) { + return NULL; + } + if (ex->symbol_table) { + return ex->symbol_table; + } - if (EG(symtable_cache_ptr)>=EG(symtable_cache)) { - /*printf("Cache hit! Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/ - EG(active_symbol_table) = *(EG(symtable_cache_ptr)--); - } else { - EG(active_symbol_table) = emalloc(sizeof(zend_array)); - GC_REFCOUNT(EG(active_symbol_table)) = 0; - GC_TYPE_INFO(EG(active_symbol_table)) = IS_ARRAY; - zend_hash_init(&EG(active_symbol_table)->ht, ex->func->op_array.last_var, NULL, ZVAL_PTR_DTOR, 0); - /*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/ - } - ex->symbol_table = EG(active_symbol_table); - for (i = 0; i < ex->func->op_array.last_var; i++) { - zval zv; + if (EG(symtable_cache_ptr) >= EG(symtable_cache)) { + /*printf("Cache hit! Reusing %x\n", symtable_cache[symtable_cache_ptr]);*/ + symbol_table = ex->symbol_table = *(EG(symtable_cache_ptr)--); + } else { + symbol_table = ex->symbol_table = emalloc(sizeof(zend_array)); + GC_REFCOUNT(symbol_table) = 0; + GC_TYPE_INFO(symbol_table) = IS_ARRAY; + zend_hash_init(&symbol_table->ht, ex->func->op_array.last_var, NULL, ZVAL_PTR_DTOR, 0); + /*printf("Cache miss! Initialized %x\n", EG(active_symbol_table));*/ + } + for (i = 0; i < ex->func->op_array.last_var; i++) { + zval zv; - ZVAL_INDIRECT(&zv, EX_VAR_NUM_2(ex, i)); - zend_hash_add_new(&EG(active_symbol_table)->ht, - ex->func->op_array.vars[i], &zv); - } + ZVAL_INDIRECT(&zv, EX_VAR_NUM_2(ex, i)); + zend_hash_add_new(&symbol_table->ht, + ex->func->op_array.vars[i], &zv); } + return symbol_table; } /* }}} */ @@ -1700,18 +1684,18 @@ ZEND_API void zend_detach_symbol_table(zend_execute_data *execute_data) /* {{{ * ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force TSRMLS_DC) /* {{{ */ { - if (!EG(active_symbol_table)) { - int i; - zend_execute_data *execute_data = EG(current_execute_data); - zend_op_array *op_array; - zend_ulong h = STR_HASH_VAL(name); - - while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) { - execute_data = execute_data->prev_execute_data; - } + zend_execute_data *execute_data = EG(current_execute_data); + + while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) { + execute_data = execute_data->prev_execute_data; + } + + if (execute_data) { + if (!execute_data->symbol_table) { + zend_ulong h = STR_HASH_VAL(name); + zend_op_array *op_array = &execute_data->func->op_array; + int i; - if (execute_data && execute_data->func) { - op_array = &execute_data->func->op_array; for (i = 0; i < op_array->last_var; i++) { if (op_array->vars[i]->h == h && op_array->vars[i]->len == name->len && @@ -1720,36 +1704,34 @@ ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force TSRMLS return SUCCESS; } } - } - if (force) { - zend_rebuild_symbol_table(TSRMLS_C); - if (EG(active_symbol_table)) { - zend_hash_update(&EG(active_symbol_table)->ht, name, value); + if (force) { + zend_array *symbol_table = zend_rebuild_symbol_table(TSRMLS_C); + if (symbol_table) { + return zend_hash_update(&symbol_table->ht, name, value) ? SUCCESS : FAILURE;; + } } } else { - return FAILURE; + return (zend_hash_update_ind(&execute_data->symbol_table->ht, name, value) != NULL) ? SUCCESS : FAILURE; } - } else { - return (zend_hash_update_ind(&EG(active_symbol_table)->ht, name, value) != NULL) ? SUCCESS : FAILURE; } - return SUCCESS; + return FAILURE; } /* }}} */ ZEND_API int zend_set_local_var_str(const char *name, int len, zval *value, int force TSRMLS_DC) /* {{{ */ { - if (!EG(active_symbol_table)) { - int i; - zend_execute_data *execute_data = EG(current_execute_data); - zend_op_array *op_array; - zend_ulong h = zend_hash_func(name, len); - - while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) { - execute_data = execute_data->prev_execute_data; - } + zend_execute_data *execute_data = EG(current_execute_data); + + while (execute_data && (!execute_data->func || !ZEND_USER_CODE(execute_data->func->common.type))) { + execute_data = execute_data->prev_execute_data; + } + + if (execute_data) { + if (!execute_data->symbol_table) { + zend_ulong h = zend_hash_func(name, len); + zend_op_array *op_array = &execute_data->func->op_array; + int i; - if (execute_data && execute_data->func) { - op_array = &execute_data->func->op_array; for (i = 0; i < op_array->last_var; i++) { if (op_array->vars[i]->h == h && op_array->vars[i]->len == len && @@ -1758,19 +1740,18 @@ ZEND_API int zend_set_local_var_str(const char *name, int len, zval *value, int return SUCCESS; } } - } - if (force) { - zend_rebuild_symbol_table(TSRMLS_C); - if (EG(active_symbol_table)) { - zend_hash_str_update(&EG(active_symbol_table)->ht, name, len, value); + + if (force) { + zend_array *symbol_table = zend_rebuild_symbol_table(TSRMLS_C); + if (symbol_table) { + return zend_hash_str_update(&symbol_table->ht, name, len, value) ? SUCCESS : FAILURE;; + } } } else { - return FAILURE; + return (zend_hash_str_update_ind(&execute_data->symbol_table->ht, name, len, value) != NULL) ? SUCCESS : FAILURE; } - } else { - return (zend_hash_str_update_ind(&EG(active_symbol_table)->ht, name, len, value) != NULL) ? SUCCESS : FAILURE; } - return SUCCESS; + return FAILURE; } /* }}} */ -- cgit v1.2.1 From 5aa91be509731eb46acff242412941325122ab03 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 7 Jul 2014 15:50:44 +0400 Subject: Simplify call-frame handling --- Zend/zend_execute_API.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 6730bacf40..69f7cfad5b 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -39,7 +39,7 @@ #endif ZEND_API void (*zend_execute_ex)(zend_execute_data *execute_data TSRMLS_DC); -ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data_ptr, zend_fcall_info *fci TSRMLS_DC); +ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data, zval *return_value TSRMLS_DC); /* true globals */ ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, {{0},0}, NULL, NULL, 0, NULL, NULL, 0 }; @@ -468,7 +468,7 @@ ZEND_API uint zend_get_executed_lineno(TSRMLS_D) /* {{{ */ while (ex && (!ex->func || !ZEND_USER_CODE(ex->func->type))) { ex = ex->prev_execute_data; } - if (ex && ex->opline) { + if (ex) { if (EG(exception) && ex->opline->opcode == ZEND_HANDLE_EXCEPTION && ex->opline->lineno == 0 && EG(opline_before_exception)) { return EG(opline_before_exception)->lineno; @@ -697,7 +697,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS */ memset(&dummy_execute_data, 0, sizeof(zend_execute_data)); EG(current_execute_data) = &dummy_execute_data; - } else if (EG(current_execute_data)->opline && + } 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) { /* Insert fake frame in case of include or magic calls */ dummy_execute_data = *EG(current_execute_data); @@ -741,7 +742,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } func = fci_cache->function_handler; - call = zend_vm_stack_push_call_frame(func, fci->param_count, ZEND_CALL_DONE, fci_cache->called_scope, fci_cache->object, NULL TSRMLS_CC); + call = zend_vm_stack_push_call_frame(func, fci->param_count, 0, fci_cache->called_scope, fci_cache->object, NULL TSRMLS_CC); calling_scope = fci_cache->calling_scope; fci->object = fci_cache->object; if (fci->object && @@ -843,16 +844,14 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS Z_ADDREF(EG(This)); } - call->prev_nested_call = EG(current_execute_data)->call; - EG(current_execute_data)->call = call; - if (func->type == ZEND_USER_FUNCTION) { EG(scope) = func->common.scope; call->symbol_table = fci->symbol_table; if (EXPECTED((func->op_array.fn_flags & ZEND_ACC_GENERATOR) == 0)) { - zend_execute(&func->op_array, fci->retval TSRMLS_CC); + zend_init_execute_data(call, &func->op_array, fci->retval, call->symbol_table ? VM_FRAME_TOP_CODE : VM_FRAME_TOP_FUNCTION TSRMLS_CC); + zend_execute_ex(call TSRMLS_CC); } else { - zend_generator_create_zval(&func->op_array, fci->retval TSRMLS_CC); + zend_generator_create_zval(call, &func->op_array, fci->retval TSRMLS_CC); } } else if (func->type == ZEND_INTERNAL_FUNCTION) { int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0; @@ -860,19 +859,16 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS if (func->common.scope) { EG(scope) = func->common.scope; } - call->opline = NULL; - call->call = NULL; call->prev_execute_data = EG(current_execute_data); EG(current_execute_data) = call; if (EXPECTED(zend_execute_internal == NULL)) { /* saves one function call if zend_execute_internal is not used */ func->internal_function.handler(fci->param_count, fci->retval TSRMLS_CC); } else { - zend_execute_internal(call->prev_execute_data, fci TSRMLS_CC); + zend_execute_internal(call, fci->retval TSRMLS_CC); } EG(current_execute_data) = call->prev_execute_data; zend_vm_stack_free_args(call TSRMLS_CC); - EG(current_execute_data)->call = call->prev_nested_call; zend_vm_stack_free_call_frame(call TSRMLS_CC); /* We shouldn't fix bad extensions here, @@ -895,8 +891,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS /* Not sure what should be done here if it's a static method */ if (fci->object) { - call->opline = NULL; - call->call = NULL; call->prev_execute_data = EG(current_execute_data); EG(current_execute_data) = call; fci->object->handlers->call_method(func->common.function_name, fci->object, fci->param_count, fci->retval TSRMLS_CC); @@ -906,7 +900,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } zend_vm_stack_free_args(call TSRMLS_CC); - EG(current_execute_data)->call = call->prev_nested_call; zend_vm_stack_free_call_frame(call TSRMLS_CC); if (func->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) { @@ -1098,11 +1091,6 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s zend_try { ZVAL_UNDEF(&local_retval); - if (EG(current_execute_data)) { - EG(current_execute_data)->call = zend_vm_stack_push_call_frame( - (zend_function*)new_op_array, 0, 0, EG(current_execute_data)->called_scope, Z_OBJ(EG(This)), EG(current_execute_data)->call TSRMLS_CC); - EG(current_execute_data)->call->symbol_table = zend_rebuild_symbol_table(TSRMLS_C); - } zend_execute(new_op_array, &local_retval TSRMLS_CC); } zend_catch { destroy_op_array(new_op_array TSRMLS_CC); -- cgit v1.2.1 From 21acbd5b75b3c77babbfe792e53d790d6c191182 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 7 Jul 2014 21:33:53 +0400 Subject: Avoid useless check --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 69f7cfad5b..509cb91113 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -848,7 +848,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EG(scope) = func->common.scope; call->symbol_table = fci->symbol_table; if (EXPECTED((func->op_array.fn_flags & ZEND_ACC_GENERATOR) == 0)) { - zend_init_execute_data(call, &func->op_array, fci->retval, call->symbol_table ? VM_FRAME_TOP_CODE : VM_FRAME_TOP_FUNCTION TSRMLS_CC); + zend_init_execute_data(call, &func->op_array, fci->retval, VM_FRAME_TOP_FUNCTION TSRMLS_CC); zend_execute_ex(call TSRMLS_CC); } else { zend_generator_create_zval(call, &func->op_array, fci->retval TSRMLS_CC); -- cgit v1.2.1 From de306e70882dd7dd04ea952ef3c665304837c3be Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 11 Jul 2014 00:32:18 +0400 Subject: Implement call_user_func() and call_user_func_array() using special opcodes. In some rare cases it leads to insignificant changes in error messages. --- Zend/zend_execute_API.c | 1 - 1 file changed, 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 509cb91113..308d54b31d 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -825,7 +825,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } else if (Z_ISREF(fci->params[i]) && /* don't separate references for __call */ (func->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) == 0 ) { - param = &tmp; param = ZEND_CALL_ARG(call, i+1); ZVAL_DUP(param, Z_REFVAL(fci->params[i])); } else { -- cgit v1.2.1 From edd9fcab1e2da36e9f6e0261bb7c3187548759c0 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 26 Jul 2014 18:08:31 +0200 Subject: Fix leaks Must find a good way to handle constant expressions... --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 308d54b31d..5ac8eab068 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -606,7 +606,7 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope TSRMLS_CC); if (inline_change) { - zend_ast_destroy(Z_ASTVAL_P(p)); + zend_ast_destroy_and_free(Z_ASTVAL_P(p)); efree(Z_AST_P(p)); } ZVAL_COPY_VALUE(p, &tmp); -- cgit v1.2.1 From 55f53e29a0abde732eabf8364c289fdd4e97d7df Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 28 Jul 2014 15:39:43 +0200 Subject: zend_get_class_fetch_type works on zend_string --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 5ac8eab068..bdf87bd440 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1467,7 +1467,7 @@ check_fetch_type: } return EG(current_execute_data)->called_scope; case ZEND_FETCH_CLASS_AUTO: { - fetch_type = zend_get_class_fetch_type(class_name->val, class_name->len); + fetch_type = zend_get_class_fetch_type(class_name); if (fetch_type!=ZEND_FETCH_CLASS_DEFAULT) { goto check_fetch_type; } -- cgit v1.2.1 From c201ba8fffd967b9cc5dcf18bd46cc9d025cb955 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 31 Jul 2014 10:51:49 +0400 Subject: execute_data->return_value should be initialized when call internal constructors --- Zend/zend_execute_API.c | 1 + 1 file changed, 1 insertion(+) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 308d54b31d..9e9bd841a0 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -859,6 +859,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EG(scope) = func->common.scope; } call->prev_execute_data = EG(current_execute_data); + call->return_value = NULL; /* this is not a constructor call */ EG(current_execute_data) = call; if (EXPECTED(zend_execute_internal == NULL)) { /* saves one function call if zend_execute_internal is not used */ -- cgit v1.2.1 From 32314f6b6715ec6bfd5a2d88310768e2fa9bf707 Mon Sep 17 00:00:00 2001 From: Keyur Govande Date: Thu, 14 Aug 2014 00:55:14 +0000 Subject: Fix destruction order in zend_shutdown (bug #65463, #66036) If Apache or a similar SAPI receives a signal during PHP processing it calls zend_shutdown() without calling shutdown_executor(). #65463: If a module like Gearman or Memcached is loaded, in the unfixed version it is unloaded by zend_destroy_modules() before the CG(CLASS_TABLE) is destructed. When CG(CLASS_TABLE) is destructed, any pointers to methods (specifically around destruction) in the unloaded module's .so are now dangling and the process segfaults. #66036: Any subclasses of an internal class like ArrayObject need to be destructed in order: subclass first and then the internal class. In the unfixed version zend_shutdown() clears the CG(CLASS_TABLE) from the head of the list onwards, so internal classes are destructed first and user-defined classes last. Internal classes are alloc/deallocated with malloc/free while user-defined classes with emalloc/efree. If there's shared data between them then efree() could be called instead of free() leading to a seg-fault. --- Zend/zend_execute_API.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index a38504fbb4..9efc13bf85 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -108,19 +108,19 @@ static int clean_non_persistent_function(zend_function *function TSRMLS_DC) /* { } /* }}} */ -static int clean_non_persistent_function_full(zend_function *function TSRMLS_DC) /* {{{ */ +ZEND_API int clean_non_persistent_function_full(zend_function *function TSRMLS_DC) /* {{{ */ { return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE; } /* }}} */ -static int clean_non_persistent_class(zend_class_entry **ce TSRMLS_DC) /* {{{ */ +ZEND_API int clean_non_persistent_class(zend_class_entry **ce TSRMLS_DC) /* {{{ */ { return ((*ce)->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE; } /* }}} */ -static int clean_non_persistent_class_full(zend_class_entry **ce TSRMLS_DC) /* {{{ */ +ZEND_API int clean_non_persistent_class_full(zend_class_entry **ce TSRMLS_DC) /* {{{ */ { return ((*ce)->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE; } -- cgit v1.2.1 From 5e338836ff4f52107ae722322ffe92b8cd7d3aa3 Mon Sep 17 00:00:00 2001 From: Keyur Govande Date: Thu, 14 Aug 2014 01:14:11 +0000 Subject: Fix typo from commit 32314f6b6 --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 9efc13bf85..0f8f41811b 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -114,7 +114,7 @@ ZEND_API int clean_non_persistent_function_full(zend_function *function TSRMLS_D } /* }}} */ -ZEND_API int clean_non_persistent_class(zend_class_entry **ce TSRMLS_DC) /* {{{ */ +static int clean_non_persistent_class(zend_class_entry **ce TSRMLS_DC) /* {{{ */ { return ((*ce)->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_STOP : ZEND_HASH_APPLY_REMOVE; } -- cgit v1.2.1 From d7f12b9b9c2312ad8ba7edfd6544b64d7de2aaec Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Fri, 15 Aug 2014 13:52:52 +0800 Subject: Fixed initializing --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 9e9bd841a0..8af877215c 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -42,7 +42,7 @@ ZEND_API void (*zend_execute_ex)(zend_execute_data *execute_data TSRMLS_DC); ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data, zval *return_value TSRMLS_DC); /* true globals */ -ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, {{0},0}, NULL, NULL, 0, NULL, NULL, 0 }; +ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, {{0}, {{0}}, {0}}, NULL, NULL, 0, NULL, NULL, 0 }; ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, NULL }; #ifdef ZEND_WIN32 -- cgit v1.2.1 From 8ee2a4a9b5de682c0b37670e1f4f86242b1650ce Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sat, 16 Aug 2014 11:16:11 +0200 Subject: first shot on merging the core fro the int64 branch --- Zend/zend_execute_API.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 8af877215c..1b33903723 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -531,11 +531,11 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas if (!const_value) { char *actual = Z_STRVAL_P(p); - if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) { + if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRSIZE_P(p)))) { int len; zend_error(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(p)); - len = Z_STRLEN_P(p) - ((colon - Z_STRVAL_P(p)) + 1); + len = Z_STRSIZE_P(p) - ((colon - Z_STRVAL_P(p)) + 1); if (inline_change) { zend_string *tmp = STR_INIT(colon + 1, len, 0); STR_RELEASE(Z_STR_P(p)); @@ -547,7 +547,7 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas } else { zend_string *save = Z_STR_P(p); char *slash; - int actual_len = Z_STRLEN_P(p); + int actual_len = Z_STRSIZE_P(p); if ((Z_CONST_FLAGS_P(p) & IS_CONSTANT_UNQUALIFIED) && (slash = (char *)zend_memrchr(actual, '\\', actual_len))) { actual = slash + 1; actual_len -= (actual - Z_STRVAL_P(p)); @@ -559,8 +559,8 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas } if (actual[0] == '\\') { if (inline_change) { - memmove(Z_STRVAL_P(p), Z_STRVAL_P(p)+1, Z_STRLEN_P(p)); - --Z_STRLEN_P(p); + memmove(Z_STRVAL_P(p), Z_STRVAL_P(p)+1, Z_STRSIZE_P(p)); + --Z_STRSIZE_P(p); } else { ++actual; } @@ -1069,8 +1069,8 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s ZVAL_NEW_STR(&pv, STR_ALLOC(str_len + sizeof("return ;")-1, 1)); memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1); memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, str, str_len); - Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';'; - Z_STRVAL(pv)[Z_STRLEN(pv)] = '\0'; + Z_STRVAL(pv)[Z_STRSIZE(pv) - 1] = ';'; + Z_STRVAL(pv)[Z_STRSIZE(pv)] = '\0'; } else { ZVAL_STRINGL(&pv, str, str_len); } @@ -1183,7 +1183,7 @@ void execute_new_code(TSRMLS_D) /* {{{ */ } switch (opline->opcode) { case ZEND_GOTO: - if (Z_TYPE_P(opline->op2.zv) != IS_LONG) { + if (Z_TYPE_P(opline->op2.zv) != IS_INT) { zend_resolve_goto_label(CG(active_op_array), opline, 1 TSRMLS_CC); } /* break omitted intentionally */ @@ -1360,7 +1360,7 @@ void zend_shutdown_timeout_thread(void) /* {{{ */ #define SIGPROF 27 #endif -void zend_set_timeout(long seconds, int reset_signals) /* {{{ */ +void zend_set_timeout(zend_int_t seconds, int reset_signals) /* {{{ */ { TSRMLS_FETCH(); -- cgit v1.2.1 From 5bb25776a00e1074d1230a311043b00f7cce9252 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sat, 16 Aug 2014 15:34:04 +0200 Subject: further fixes on core --- Zend/zend_execute_API.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 1b33903723..eba2d39c5f 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1680,7 +1680,7 @@ ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force TSRMLS if (execute_data) { if (!execute_data->symbol_table) { - zend_ulong h = STR_HASH_VAL(name); + zend_uint_t h = STR_HASH_VAL(name); zend_op_array *op_array = &execute_data->func->op_array; int i; @@ -1716,7 +1716,7 @@ ZEND_API int zend_set_local_var_str(const char *name, int len, zval *value, int if (execute_data) { if (!execute_data->symbol_table) { - zend_ulong h = zend_hash_func(name, len); + zend_uint_t h = zend_hash_func(name, len); zend_op_array *op_array = &execute_data->func->op_array; int i; -- cgit v1.2.1 From 26a9dc3e04813a76bf59ffb5bf9df47f6034008b Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 18 Aug 2014 18:12:50 +0200 Subject: Fix bug #67858: Leak when $php_errormsg already set --- Zend/zend_execute_API.c | 1 + 1 file changed, 1 insertion(+) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 8af877215c..b45a021650 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1724,6 +1724,7 @@ ZEND_API int zend_set_local_var_str(const char *name, int len, zval *value, int if (op_array->vars[i]->h == h && op_array->vars[i]->len == len && memcmp(op_array->vars[i]->val, name, len) == 0) { + zval_ptr_dtor(EX_VAR_NUM(i)); ZVAL_COPY_VALUE(EX_VAR_NUM(i), value); return SUCCESS; } -- cgit v1.2.1 From c3e3c98ec666812daaaca896cf5ef758a8a6df14 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Mon, 25 Aug 2014 19:24:55 +0200 Subject: master renames phase 1 --- Zend/zend_execute_API.c | 64 ++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index d2a704259b..c8a3c41afa 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -531,36 +531,36 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas if (!const_value) { char *actual = Z_STRVAL_P(p); - if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRSIZE_P(p)))) { + if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) { int len; zend_error(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(p)); - len = Z_STRSIZE_P(p) - ((colon - Z_STRVAL_P(p)) + 1); + len = Z_STRLEN_P(p) - ((colon - Z_STRVAL_P(p)) + 1); if (inline_change) { - zend_string *tmp = STR_INIT(colon + 1, len, 0); - STR_RELEASE(Z_STR_P(p)); + zend_string *tmp = zend_string_init(colon + 1, len, 0); + zend_string_release(Z_STR_P(p)); Z_STR_P(p) = tmp; } else { - Z_STR_P(p) = STR_INIT(colon + 1, len, 0); + Z_STR_P(p) = zend_string_init(colon + 1, len, 0); } Z_TYPE_FLAGS_P(p) = IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE; } else { zend_string *save = Z_STR_P(p); char *slash; - int actual_len = Z_STRSIZE_P(p); + int actual_len = Z_STRLEN_P(p); if ((Z_CONST_FLAGS_P(p) & IS_CONSTANT_UNQUALIFIED) && (slash = (char *)zend_memrchr(actual, '\\', actual_len))) { actual = slash + 1; actual_len -= (actual - Z_STRVAL_P(p)); if (inline_change) { - zend_string *s = STR_INIT(actual, actual_len, 0); + zend_string *s = zend_string_init(actual, actual_len, 0); Z_STR_P(p) = s; Z_TYPE_FLAGS_P(p) = IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE; } } if (actual[0] == '\\') { if (inline_change) { - memmove(Z_STRVAL_P(p), Z_STRVAL_P(p)+1, Z_STRSIZE_P(p)); - --Z_STRSIZE_P(p); + memmove(Z_STRVAL_P(p), Z_STRVAL_P(p)+1, Z_STRLEN_P(p)); + --Z_STRLEN_P(p); } else { ++actual; } @@ -573,7 +573,7 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas zend_error(E_ERROR, "Undefined constant '%s'", save->val); } if (inline_change) { - STR_RELEASE(save); + zend_string_release(save); } save = NULL; } @@ -584,13 +584,13 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas Z_TYPE_INFO_P(p) = IS_INTERNED(Z_STR_P(p)) ? IS_INTERNED_STRING_EX : IS_STRING_EX; if (save && save->val != actual) { - STR_RELEASE(save); + zend_string_release(save); } } } } else { if (inline_change) { - STR_RELEASE(Z_STR_P(p)); + zend_string_release(Z_STR_P(p)); } ZVAL_COPY_VALUE(p, const_value); if (Z_OPT_CONSTANT_P(p)) { @@ -724,7 +724,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS efree(error); } if (callable_name) { - STR_RELEASE(callable_name); + zend_string_release(callable_name); } if (EG(current_execute_data) == &dummy_execute_data) { EG(current_execute_data) = dummy_execute_data.prev_execute_data; @@ -738,7 +738,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_error(E_STRICT, "%s", error); efree(error); } - STR_RELEASE(callable_name); + zend_string_release(callable_name); } func = fci_cache->function_handler; @@ -903,7 +903,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_vm_stack_free_call_frame(call TSRMLS_CC); if (func->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY) { - STR_RELEASE(func->common.function_name); + zend_string_release(func->common.function_name); } efree(func); @@ -948,10 +948,10 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k } if (name->val[0] == '\\') { - lc_name = STR_ALLOC(name->len - 1, 0); + lc_name = zend_string_alloc(name->len - 1, 0); zend_str_tolower_copy(lc_name->val, name->val + 1, name->len - 1); } else { - lc_name = STR_ALLOC(name->len, 0); + lc_name = zend_string_alloc(name->len, 0); zend_str_tolower_copy(lc_name->val, name->val, name->len); } } @@ -959,7 +959,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k ce = zend_hash_find_ptr(EG(class_table), lc_name); if (ce) { if (!key) { - STR_FREE(lc_name); + zend_string_free(lc_name); } return ce; } @@ -969,7 +969,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k */ if (!use_autoload || zend_is_compiling(TSRMLS_C)) { if (!key) { - STR_FREE(lc_name); + zend_string_free(lc_name); } return NULL; } @@ -980,7 +980,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k EG(autoload_func) = func; } else { if (!key) { - STR_FREE(lc_name); + zend_string_free(lc_name); } return NULL; } @@ -990,7 +990,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k /* Verify class name before passing it to __autoload() */ if (strspn(name->val, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\") != name->len) { if (!key) { - STR_FREE(lc_name); + zend_string_free(lc_name); } return NULL; } @@ -1002,7 +1002,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k if (zend_hash_add_empty_element(EG(in_autoload), lc_name) == NULL) { if (!key) { - STR_FREE(lc_name); + zend_string_free(lc_name); } return NULL; } @@ -1012,12 +1012,12 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k if (name->val[0] == '\\') { ZVAL_STRINGL(&args[0], name->val + 1, name->len - 1); } else { - ZVAL_STR(&args[0], STR_COPY(name)); + ZVAL_STR(&args[0], zend_string_copy(name)); } fcall_info.size = sizeof(fcall_info); fcall_info.function_table = EG(function_table); - ZVAL_STR(&fcall_info.function_name, STR_COPY(EG(autoload_func)->common.function_name)); + ZVAL_STR(&fcall_info.function_name, zend_string_copy(EG(autoload_func)->common.function_name)); fcall_info.symbol_table = NULL; fcall_info.retval = &local_retval; fcall_info.param_count = 1; @@ -1046,7 +1046,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k ce = zend_hash_find_ptr(EG(class_table), lc_name); } if (!key) { - STR_FREE(lc_name); + zend_string_free(lc_name); } return ce; } @@ -1066,11 +1066,11 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s int retval; if (retval_ptr) { - ZVAL_NEW_STR(&pv, STR_ALLOC(str_len + sizeof("return ;")-1, 1)); + ZVAL_NEW_STR(&pv, zend_string_alloc(str_len + sizeof("return ;")-1, 1)); memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1); memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, str, str_len); - Z_STRVAL(pv)[Z_STRSIZE(pv) - 1] = ';'; - Z_STRVAL(pv)[Z_STRSIZE(pv)] = '\0'; + Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';'; + Z_STRVAL(pv)[Z_STRLEN(pv)] = '\0'; } else { ZVAL_STRINGL(&pv, str, str_len); } @@ -1183,7 +1183,7 @@ void execute_new_code(TSRMLS_D) /* {{{ */ } switch (opline->opcode) { case ZEND_GOTO: - if (Z_TYPE_P(opline->op2.zv) != IS_INT) { + if (Z_TYPE_P(opline->op2.zv) != IS_LONG) { zend_resolve_goto_label(CG(active_op_array), opline, 1 TSRMLS_CC); } /* break omitted intentionally */ @@ -1360,7 +1360,7 @@ void zend_shutdown_timeout_thread(void) /* {{{ */ #define SIGPROF 27 #endif -void zend_set_timeout(zend_int_t seconds, int reset_signals) /* {{{ */ +void zend_set_timeout(zend_long seconds, int reset_signals) /* {{{ */ { TSRMLS_FETCH(); @@ -1680,7 +1680,7 @@ ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force TSRMLS if (execute_data) { if (!execute_data->symbol_table) { - zend_uint_t h = STR_HASH_VAL(name); + zend_ulong h = zend_string_hash_val(name); zend_op_array *op_array = &execute_data->func->op_array; int i; @@ -1716,7 +1716,7 @@ ZEND_API int zend_set_local_var_str(const char *name, int len, zval *value, int if (execute_data) { if (!execute_data->symbol_table) { - zend_uint_t h = zend_hash_func(name, len); + zend_ulong h = zend_hash_func(name, len); zend_op_array *op_array = &execute_data->func->op_array; int i; -- cgit v1.2.1 From 6f9f0bf2056f0dc17d9bcc6dd3b7d28ac878c6fc Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Mon, 25 Aug 2014 19:28:33 +0200 Subject: master renames phase 2 --- Zend/zend_execute_API.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index c8a3c41afa..af309c5e64 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -633,13 +633,13 @@ ZEND_API int zval_update_constant(zval *pp, zend_bool inline_change TSRMLS_DC) / } /* }}} */ -int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, zend_uint param_count, zval params[] TSRMLS_DC) /* {{{ */ +int call_user_function(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, uint32_t param_count, zval params[] TSRMLS_DC) /* {{{ */ { return call_user_function_ex(function_table, object, function_name, retval_ptr, param_count, params, 1, NULL TSRMLS_CC); } /* }}} */ -int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, zend_uint param_count, zval params[], int no_separation, zend_array *symbol_table TSRMLS_DC) /* {{{ */ +int call_user_function_ex(HashTable *function_table, zval *object, zval *function_name, zval *retval_ptr, uint32_t param_count, zval params[], int no_separation, zend_array *symbol_table TSRMLS_DC) /* {{{ */ { zend_fcall_info fci; @@ -659,7 +659,7 @@ int call_user_function_ex(HashTable *function_table, zval *object, zval *functio int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TSRMLS_DC) /* {{{ */ { - zend_uint i; + uint32_t i; zend_class_entry *calling_scope = NULL; zend_execute_data *call, dummy_execute_data; zend_fcall_info_cache fci_cache_local; @@ -1062,7 +1062,7 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s { zval pv; zend_op_array *new_op_array; - zend_uint original_compiler_options; + uint32_t original_compiler_options; int retval; if (retval_ptr) { @@ -1584,7 +1584,7 @@ ZEND_API int zend_delete_global_variable(zend_string *name TSRMLS_DC) /* {{{ */ ZEND_API zend_array *zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ { - zend_uint i; + uint32_t i; zend_execute_data *ex; zend_array *symbol_table; -- cgit v1.2.1 From d2a3bf9daf41471c93327d5aaafbef8a7dde9053 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 25 Aug 2014 23:05:05 +0200 Subject: Fix compiler warnings --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 461225da99..e43743c1dc 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1243,7 +1243,7 @@ ZEND_API void zend_timeout(int dummy) /* {{{ */ zend_on_timeout(EG(timeout_seconds) TSRMLS_CC); } - zend_error(E_ERROR, "Maximum execution time of %d second%s exceeded", EG(timeout_seconds), EG(timeout_seconds) == 1 ? "" : "s"); + zend_error(E_ERROR, "Maximum execution time of %pd second%s exceeded", EG(timeout_seconds), EG(timeout_seconds) == 1 ? "" : "s"); } /* }}} */ -- cgit v1.2.1 From 59848e3fbbcab3144c4d711df5d5be39cca51269 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Mon, 25 Aug 2014 23:45:02 +0200 Subject: Remove ZEND_ACC_INTERACTIVE and CG(interactive) As far as I can discern these are leftovers of the interactive shell implementation that was used before PHP 5.4. Now the readline ext makes use of normal eval calls for this. So, dropping these until there is evidence to the contrary, as they currently wouldn't work anyway. --- Zend/zend_execute_API.c | 81 ------------------------------------------------- 1 file changed, 81 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index e43743c1dc..46ee2b2312 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1084,10 +1084,8 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s if (new_op_array) { zval local_retval; - int orig_interactive = CG(interactive); EG(no_extensions)=1; - CG(interactive) = 0; zend_try { ZVAL_UNDEF(&local_retval); @@ -1098,7 +1096,6 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s zend_bailout(); } zend_end_try(); - CG(interactive) = orig_interactive; if (Z_TYPE(local_retval) != IS_UNDEF) { if (retval_ptr) { ZVAL_COPY_VALUE(retval_ptr, &local_retval); @@ -1148,84 +1145,6 @@ ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, } /* }}} */ -void execute_new_code(TSRMLS_D) /* {{{ */ -{ - zend_op *opline, *end; - zend_op *ret_opline; - int orig_interactive; - - if (!(CG(active_op_array)->fn_flags & ZEND_ACC_INTERACTIVE) - || CG(context).backpatch_count>0 - || CG(active_op_array)->function_name - || CG(active_op_array)->type!=ZEND_USER_FUNCTION) { - return; - } - - ret_opline = get_next_op(CG(active_op_array) TSRMLS_CC); - ret_opline->opcode = ZEND_RETURN; - ret_opline->op1_type = IS_CONST; - ret_opline->op1.constant = zend_add_literal(CG(active_op_array), &EG(uninitialized_zval) TSRMLS_CC); - SET_UNUSED(ret_opline->op2); - - if (!EG(start_op)) { - EG(start_op) = CG(active_op_array)->opcodes; - } - - opline=EG(start_op); - end=CG(active_op_array)->opcodes+CG(active_op_array)->last; - - while (oplineop1_type == IS_CONST) { - opline->op1.zv = &CG(active_op_array)->literals[opline->op1.constant]; - } - if (opline->op2_type == IS_CONST) { - opline->op2.zv = &CG(active_op_array)->literals[opline->op2.constant]; - } - switch (opline->opcode) { - case ZEND_GOTO: - if (Z_TYPE_P(opline->op2.zv) != IS_LONG) { - zend_resolve_goto_label(CG(active_op_array), opline, 1 TSRMLS_CC); - } - /* break omitted intentionally */ - case ZEND_JMP: - opline->op1.jmp_addr = &CG(active_op_array)->opcodes[opline->op1.opline_num]; - break; - case ZEND_JMPZNZ: - /* absolute index to relative offset */ - opline->extended_value = (char*)(CG(active_op_array)->opcodes + opline->extended_value) - (char*)opline; - /* break omitted intentionally */ - case ZEND_JMPZ: - case ZEND_JMPNZ: - case ZEND_JMPZ_EX: - case ZEND_JMPNZ_EX: - case ZEND_JMP_SET: - case ZEND_JMP_SET_VAR: - case ZEND_NEW: - case ZEND_FE_RESET: - case ZEND_FE_FETCH: - opline->op2.jmp_addr = &CG(active_op_array)->opcodes[opline->op2.opline_num]; - break; - } - ZEND_VM_SET_OPCODE_HANDLER(opline); - opline++; - } - - zend_release_labels(1 TSRMLS_CC); - - orig_interactive = CG(interactive); - CG(interactive) = 0; - zend_execute(CG(active_op_array), NULL TSRMLS_CC); - CG(interactive) = orig_interactive; - - if (EG(exception)) { - zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); - } - - CG(active_op_array)->last -= 1; /* get rid of that ZEND_RETURN */ - EG(start_op) = CG(active_op_array)->opcodes+CG(active_op_array)->last; -} -/* }}} */ - ZEND_API void zend_timeout(int dummy) /* {{{ */ { TSRMLS_FETCH(); -- cgit v1.2.1 From b1f53ca4157c2b544108e4af26dfe372b7158bf3 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 27 Aug 2014 20:49:56 +0400 Subject: Use efree_size() instead of efree() where posible --- Zend/zend_execute_API.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 46ee2b2312..37352c9106 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -607,7 +607,7 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope TSRMLS_CC); if (inline_change) { zend_ast_destroy_and_free(Z_ASTVAL_P(p)); - efree(Z_AST_P(p)); + efree_size(Z_AST_P(p), sizeof(zend_ast_ref)); } ZVAL_COPY_VALUE(p, &tmp); } @@ -1092,7 +1092,7 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s zend_execute(new_op_array, &local_retval TSRMLS_CC); } zend_catch { destroy_op_array(new_op_array TSRMLS_CC); - efree(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); zend_bailout(); } zend_end_try(); @@ -1110,7 +1110,7 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s EG(no_extensions)=0; destroy_op_array(new_op_array TSRMLS_CC); - efree(new_op_array); + efree_size(new_op_array, sizeof(zend_op_array)); retval = SUCCESS; } else { retval = FAILURE; -- cgit v1.2.1 From b73bea9cc86468f82b6619d05e2f105d2712809e Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 29 Aug 2014 21:47:10 +0200 Subject: Combine foreach copy / switch cond stacks Now one common stack to handle both, which stores znodes instead of full oplines (foreach copy stack) or switch entries (switch cond stack). Also removed EG(start_op) while at it. --- Zend/zend_execute_API.c | 1 - 1 file changed, 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 37352c9106..5984e2dc82 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -190,7 +190,6 @@ void init_executor(TSRMLS_D) /* {{{ */ ZVAL_OBJ(&EG(This), NULL); EG(active) = 1; - EG(start_op) = NULL; } /* }}} */ -- cgit v1.2.1 From 1ff1a0dde2427e78738c93a3ac3e9b111824ee27 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 1 Sep 2014 14:35:04 -0700 Subject: Revert "Merge branch 'PHP-5.6'" This reverts commit aaf5689f4d6e523fd78e0291dbbcd78f3ea988dc, reversing changes made to 481bf25b6ad70fcdc9c10f02b49c86a0bd4a3d0d. --- Zend/zend_execute_API.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 7842ecfb91..5984e2dc82 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -110,7 +110,7 @@ static int clean_non_persistent_function(zval *zv TSRMLS_DC) /* {{{ */ } /* }}} */ -ZEND_API int clean_non_persistent_function_full(zval *zv TSRMLS_DC) /* {{{ */ +static int clean_non_persistent_function_full(zval *zv TSRMLS_DC) /* {{{ */ { zend_function *function = Z_PTR_P(zv); return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE; @@ -124,7 +124,7 @@ static int clean_non_persistent_class(zval *zv TSRMLS_DC) /* {{{ */ } /* }}} */ -ZEND_API int clean_non_persistent_class_full(zval *zv TSRMLS_DC) /* {{{ */ +static int clean_non_persistent_class_full(zval *zv TSRMLS_DC) /* {{{ */ { zend_class_entry *ce = Z_PTR_P(zv); return (ce->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE; -- cgit v1.2.1 From d5b0606a6246eee293e7ac937fcb5fdc231f61dd Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 1 Sep 2014 15:08:02 -0700 Subject: Reintroduce fix from pull #770 in a PHP 7 way --- Zend/zend_execute_API.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 5984e2dc82..7842ecfb91 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -110,7 +110,7 @@ static int clean_non_persistent_function(zval *zv TSRMLS_DC) /* {{{ */ } /* }}} */ -static int clean_non_persistent_function_full(zval *zv TSRMLS_DC) /* {{{ */ +ZEND_API int clean_non_persistent_function_full(zval *zv TSRMLS_DC) /* {{{ */ { zend_function *function = Z_PTR_P(zv); return (function->type == ZEND_INTERNAL_FUNCTION) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE; @@ -124,7 +124,7 @@ static int clean_non_persistent_class(zval *zv TSRMLS_DC) /* {{{ */ } /* }}} */ -static int clean_non_persistent_class_full(zval *zv TSRMLS_DC) /* {{{ */ +ZEND_API int clean_non_persistent_class_full(zval *zv TSRMLS_DC) /* {{{ */ { zend_class_entry *ce = Z_PTR_P(zv); return (ce->type == ZEND_INTERNAL_CLASS) ? ZEND_HASH_APPLY_KEEP : ZEND_HASH_APPLY_REMOVE; -- cgit v1.2.1 From f595ed4b8c1a6e5b95df6e2ad444816186878995 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Mon, 15 Sep 2014 11:28:24 +0200 Subject: fix initializer struct --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 7842ecfb91..09519d7083 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -42,7 +42,7 @@ ZEND_API void (*zend_execute_ex)(zend_execute_data *execute_data TSRMLS_DC); ZEND_API void (*zend_execute_internal)(zend_execute_data *execute_data, zval *return_value TSRMLS_DC); /* true globals */ -ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, {{0}, {{0}}, {0}}, NULL, NULL, 0, NULL, NULL, 0 }; +ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, {{0}, {{0}}, {0}}, NULL, NULL, NULL, NULL, 0, 0 }; ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, NULL }; #ifdef ZEND_WIN32 -- cgit v1.2.1 From e940fc268a9ac455ac4fe747d2f95f5ea597dea5 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Mon, 15 Sep 2014 16:04:12 +0200 Subject: fix signed/unsigned mismatch --- Zend/zend_execute_API.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 09519d7083..85bd441efe 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1502,7 +1502,7 @@ ZEND_API int zend_delete_global_variable(zend_string *name TSRMLS_DC) /* {{{ */ ZEND_API zend_array *zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ { - uint32_t i; + int i; zend_execute_data *ex; zend_array *symbol_table; -- cgit v1.2.1 From 3bc8a958c5ec647adbe409ee6411ae7ed6a3dc3b Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 19 Sep 2014 15:41:01 +0400 Subject: Fixed useless or duplicated IS_INTERNED() checks --- Zend/zend_execute_API.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 85bd441efe..5b3d597112 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -580,8 +580,8 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas if (!inline_change) { ZVAL_STRINGL(p, actual, actual_len); } else { - Z_TYPE_INFO_P(p) = IS_INTERNED(Z_STR_P(p)) ? - IS_INTERNED_STRING_EX : IS_STRING_EX; + Z_TYPE_INFO_P(p) = Z_REFCOUNTED_P(p) ? + IS_STRING_EX : IS_INTERNED_STRING_EX; if (save && save->val != actual) { zend_string_release(save); } -- cgit v1.2.1 From bccc653185d2fe8aa6ff83cf84db56a396c6bc05 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 19 Sep 2014 17:32:50 +0400 Subject: Avoid double IS_INTERNED() check --- Zend/zend_execute_API.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 5b3d597112..f59a10179b 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1011,12 +1011,12 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k if (name->val[0] == '\\') { ZVAL_STRINGL(&args[0], name->val + 1, name->len - 1); } else { - ZVAL_STR(&args[0], zend_string_copy(name)); + ZVAL_STR_COPY(&args[0], name); } fcall_info.size = sizeof(fcall_info); fcall_info.function_table = EG(function_table); - ZVAL_STR(&fcall_info.function_name, zend_string_copy(EG(autoload_func)->common.function_name)); + ZVAL_STR_COPY(&fcall_info.function_name, EG(autoload_func)->common.function_name); fcall_info.symbol_table = NULL; fcall_info.retval = &local_retval; fcall_info.param_count = 1; -- cgit v1.2.1 From 9f7564b12b6e57d018bbc158e00f41499017d29e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 1 Oct 2014 10:46:13 +0400 Subject: Removed zend_execute_data->prev_nested_call. Reuse prev_execute_data instead. --- Zend/zend_execute_API.c | 1 - 1 file changed, 1 deletion(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index f59a10179b..b528bd0ab5 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -703,7 +703,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS dummy_execute_data = *EG(current_execute_data); dummy_execute_data.prev_execute_data = EG(current_execute_data); dummy_execute_data.call = NULL; - dummy_execute_data.prev_nested_call = NULL; dummy_execute_data.opline = NULL; dummy_execute_data.func = NULL; EG(current_execute_data) = &dummy_execute_data; -- cgit v1.2.1 From bd9a234645772a4f3116b3c4f1d5a83efb158d80 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 3 Oct 2014 19:32:46 +0400 Subject: Replaced EG(This) and EX(object) with EX(This). Internal functions now recieves zend_execute_data as the first argument. --- Zend/zend_execute_API.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index b528bd0ab5..9fdb2ee4f5 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -187,8 +187,6 @@ void init_executor(TSRMLS_D) /* {{{ */ EG(scope) = NULL; - ZVAL_OBJ(&EG(This), NULL); - EG(active) = 1; } /* }}} */ @@ -663,7 +661,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS zend_execute_data *call, dummy_execute_data; zend_fcall_info_cache fci_cache_local; zend_function *func; - zend_object *orig_object; zend_class_entry *orig_scope; zval tmp; @@ -685,7 +682,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS break; } - orig_object = Z_OBJ(EG(This)); orig_scope = EG(scope); /* Initialize execute_data */ @@ -835,10 +831,11 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EG(scope) = calling_scope; if (!fci->object || (func->common.fn_flags & ZEND_ACC_STATIC)) { - Z_OBJ(EG(This)) = call->object = NULL; + Z_OBJ(call->This) = NULL; + Z_TYPE_INFO(call->This) = IS_UNDEF; } else { - Z_OBJ(EG(This)) = fci->object; - Z_ADDREF(EG(This)); + ZVAL_OBJ(&call->This, fci->object); + GC_REFCOUNT(fci->object)++; } if (func->type == ZEND_USER_FUNCTION) { @@ -861,7 +858,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EG(current_execute_data) = call; if (EXPECTED(zend_execute_internal == NULL)) { /* saves one function call if zend_execute_internal is not used */ - func->internal_function.handler(fci->param_count, fci->retval TSRMLS_CC); + func->internal_function.handler(call, fci->retval TSRMLS_CC); } else { zend_execute_internal(call, fci->retval TSRMLS_CC); } @@ -891,7 +888,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS if (fci->object) { call->prev_execute_data = EG(current_execute_data); EG(current_execute_data) = call; - fci->object->handlers->call_method(func->common.function_name, fci->object, fci->param_count, fci->retval TSRMLS_CC); + fci->object->handlers->call_method(func->common.function_name, fci->object, call, fci->retval TSRMLS_CC); EG(current_execute_data) = call->prev_execute_data; } else { zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object"); @@ -911,11 +908,10 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } } - if (Z_OBJ(EG(This))) { - zval_ptr_dtor(&EG(This)); + if (fci->object && !(func->common.fn_flags & ZEND_ACC_STATIC)) { + OBJ_RELEASE(fci->object); } - Z_OBJ(EG(This)) = orig_object; EG(scope) = orig_scope; if (EG(current_execute_data) == &dummy_execute_data) { EG(current_execute_data) = dummy_execute_data.prev_execute_data; -- cgit v1.2.1 From 9bc14f9632739274d7d3430759f77f272bf63241 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 5 Oct 2014 23:11:17 +0200 Subject: Fix dynamic calls to static methods with fci->object func may already be freed at the time the static flag was checked. --- Zend/zend_execute_API.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 9fdb2ee4f5..1da64bb978 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -829,8 +829,10 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS call->num_args = fci->param_count; EG(scope) = calling_scope; - if (!fci->object || - (func->common.fn_flags & ZEND_ACC_STATIC)) { + if (func->common.fn_flags & ZEND_ACC_STATIC) { + fci->object = NULL; + } + if (!fci->object) { Z_OBJ(call->This) = NULL; Z_TYPE_INFO(call->This) = IS_UNDEF; } else { @@ -908,7 +910,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } } - if (fci->object && !(func->common.fn_flags & ZEND_ACC_STATIC)) { + if (fci->object) { OBJ_RELEASE(fci->object); } -- cgit v1.2.1 From 33e137d409f552f35bf73ccb76c37b1ee0d65e2f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Tue, 7 Oct 2014 17:12:12 +0400 Subject: Merged EX(frame_kind) and EX(flags) into single word --- Zend/zend_execute_API.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 1da64bb978..f6bd9d1ca7 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -736,7 +736,8 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS } func = fci_cache->function_handler; - call = zend_vm_stack_push_call_frame(func, fci->param_count, 0, fci_cache->called_scope, fci_cache->object, NULL TSRMLS_CC); + call = zend_vm_stack_push_call_frame(VM_FRAME_TOP_FUNCTION, + func, fci->param_count, fci_cache->called_scope, fci_cache->object, NULL TSRMLS_CC); calling_scope = fci_cache->calling_scope; fci->object = fci_cache->object; if (fci->object && @@ -844,7 +845,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS EG(scope) = func->common.scope; call->symbol_table = fci->symbol_table; if (EXPECTED((func->op_array.fn_flags & ZEND_ACC_GENERATOR) == 0)) { - zend_init_execute_data(call, &func->op_array, fci->retval, VM_FRAME_TOP_FUNCTION TSRMLS_CC); + zend_init_execute_data(call, &func->op_array, fci->retval TSRMLS_CC); zend_execute_ex(call TSRMLS_CC); } else { zend_generator_create_zval(call, &func->op_array, fci->retval TSRMLS_CC); -- cgit v1.2.1 From 43f1c94ddace679cac008b674ef983199a951542 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 9 Oct 2014 12:51:05 +0200 Subject: Review a few more SEPARATE_ZVAL_IF_NOT_REF usages --- Zend/zend_execute_API.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Zend/zend_execute_API.c') diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index f6bd9d1ca7..cd2cc98b42 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -521,7 +521,7 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas } else if (Z_TYPE_P(p) == IS_CONSTANT) { int refcount; - SEPARATE_ZVAL_IF_NOT_REF(p); + SEPARATE_ZVAL_NOREF(p); MARK_CONSTANT_VISITED(p); refcount = Z_REFCOUNTED_P(p) ? Z_REFCOUNT_P(p) : 1; const_value = zend_get_constant_ex(Z_STR_P(p), scope, Z_CONST_FLAGS_P(p) TSRMLS_CC); @@ -599,7 +599,7 @@ 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_IF_NOT_REF(p); + SEPARATE_ZVAL_NOREF(p); zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope TSRMLS_CC); if (inline_change) { -- cgit v1.2.1