]> granicus.if.org Git - php/commitdiff
fixed support for constant expressions
authorDmitry Stogov <dmitry@zend.com>
Mon, 24 Feb 2014 11:25:24 +0000 (15:25 +0400)
committerDmitry Stogov <dmitry@zend.com>
Mon, 24 Feb 2014 11:25:24 +0000 (15:25 +0400)
Zend/zend_compile.c
Zend/zend_execute_API.c
Zend/zend_types.h

index 5c39e6f0b7992ed970020c25acc8fab5ec50081d..d74d0f7844043fc6e8e9ae86b0169b0710dd6412 100644 (file)
@@ -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:
index 26791c357bfaa9fbd0d2c16371ced2ff516dca01..97c3932ac8685086de9c54b2aa6b784887c82caa 100644 (file)
@@ -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);
                        }
index 5591c285b08e46055336e3aee9379ff85f62e603..9a86bc761bcf85a46bc430d4d37367b2aa52a676 100644 (file)
@@ -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)