From: Dmitry Stogov Date: Mon, 24 Feb 2014 11:25:24 +0000 (+0400) Subject: fixed support for constant expressions X-Git-Tag: POST_PHPNG_MERGE~412^2~557 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f4c2810ab45293dea7b176069b73b33bb621fbb5;p=php fixed support for constant expressions --- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 5c39e6f0b7..d74d0f7844 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -5888,26 +5888,27 @@ void zend_do_add_static_array_element(znode *result, znode *offset, const znode if (offset) { switch (Z_TYPE(offset->u.constant) & IS_CONSTANT_TYPE_MASK) { case IS_CONSTANT: - /* Ugly hack to denote that this value has a constant index */ - Z_TYPE(element) |= IS_CONSTANT_INDEX; +//??? /* Ugly hack to denote that this value has a constant index */ + Z_STR(offset->u.constant)->gc.u.v.flags |= IS_STR_CONSTANT; +//??? Z_TYPE(element) |= IS_CONSTANT_INDEX; //??? Z_STRVAL(offset->u.constant) = erealloc(Z_STRVAL(offset->u.constant), Z_STRLEN(offset->u.constant)+3); //??? Z_STRVAL(offset->u.constant)[Z_STRLEN(offset->u.constant)+1] = Z_TYPE(offset->u.constant); //??? Z_STRVAL(offset->u.constant)[Z_STRLEN(offset->u.constant)+2] = 0; -//??? zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STRVAL(offset->u.constant), Z_STRLEN(offset->u.constant)+3, &element, sizeof(zval *), NULL); + zend_symtable_update(Z_ARRVAL(result->u.constant), Z_STR(offset->u.constant), &element); zval_dtor(&offset->u.constant); break; case IS_CONSTANT_AST: { - /* Another ugly hack to store the data about the AST in the array */ -//??? char* key; +//??? /* Another ugly hack to store the data about the AST in the array */ + zend_string *key; //??? int len = sizeof(zend_ast *); - Z_TYPE(element) |= IS_CONSTANT_INDEX; +//??? Z_TYPE(element) |= IS_CONSTANT_INDEX; + Z_STR(offset->u.constant)->gc.u.v.flags |= IS_STR_AST; -//??? key = emalloc(len + 2); -//??? *(zend_ast **)key = Z_AST(offset->u.constant); + key = STR_INIT((char*)Z_AST(offset->u.constant), sizeof(zend_ast*), 0); //??? key[len] = Z_TYPE(offset->u.constant); //??? key[len + 1] = 0; -//??? zend_symtable_update(Z_ARRVAL(result->u.constant), key, len + 2, &element, sizeof(zval *), NULL); -//??? efree(key); + zend_symtable_update(Z_ARRVAL(result->u.constant), key, &element); + STR_RELEASE(key); break; } case IS_STRING: 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); } diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 5591c285b0..9a86bc761b 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -198,7 +198,7 @@ struct _zend_ast_ref { /* Ugly hack to support constants as static array indices */ #define IS_CONSTANT_TYPE_MASK 0x00f #define IS_CONSTANT_UNQUALIFIED 0x010 -#define IS_CONSTANT_INDEX 0x080 +//???#define IS_CONSTANT_INDEX 0x080 #define IS_LEXICAL_VAR 0x020 #define IS_LEXICAL_REF 0x040 #define IS_CONSTANT_IN_NAMESPACE 0x100 @@ -212,11 +212,15 @@ struct _zend_ast_ref { #define Z_TYPE(zval) (zval).type #define Z_TYPE_P(zval_p) Z_TYPE(*(zval_p)) -/* string flags (zval.value->gc.u.vflags) */ +/* string flags (zval.value->gc.u.flags) */ #define IS_STR_PERSISTENT (1<<0) /* allocated using malloc */ #define IS_STR_INTERNED (1<<1) /* interned string */ #define IS_STR_PERMANENT (1<<2) /* relives request boundary */ +#define IS_STR_CONSTANT (1<<3) /* constant index */ +#define IS_STR_CONSTANT_UNQUALIFIED (1<<4) /* the same as IS_CONSTANT_UNQUALIFIED */ +#define IS_STR_AST (1<<5) /* constant expression index */ + /* object flags (zval.value->gc.u.vflags) */ #define IS_OBJ_APPLY_COUNT 0x07 #define IS_OBJ_DESTRUCTOR_CALLED (1<<3)