diff options
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | Zend/zend_compile.c | 35 | ||||
-rw-r--r-- | Zend/zend_constants.c | 15 | ||||
-rw-r--r-- | Zend/zend_constants.h | 1 |
4 files changed, 42 insertions, 10 deletions
@@ -1,6 +1,7 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? Mar 2006, PHP 5.1.3RC2 +- Eliminated run-time constant fetching for TRUE, FALSE and NULL. (Dmitry) - Fixed offset/length parameter validation in substr_compare() function. (Ilia) - Added overflow checks to wordwrap() function. (Ilia) - Removed the E_STRICT deprecation notice from "var". (Ilia) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index f96fd44332..a967fe2f12 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3095,6 +3095,33 @@ void zend_do_end_new_object(znode *result, znode *new_token, znode *argument_lis *result = CG(active_op_array)->opcodes[new_token->u.opline_num].result; } +static int zend_constant_ct_subst(znode *result, zval *const_name TSRMLS_DC) +{ + zend_constant *c = NULL; + + if (zend_hash_find(EG(zend_constants), Z_STRVAL_P(const_name), Z_STRLEN_P(const_name)+1, (void **) &c) == FAILURE) { + char *lookup_name = zend_str_tolower_dup(Z_STRVAL_P(const_name), Z_STRLEN_P(const_name)); + + if (zend_hash_find(EG(zend_constants), lookup_name, Z_STRLEN_P(const_name)+1, (void **) &c)==SUCCESS) { + if ((c->flags & CONST_CS) && memcmp(c->name, Z_STRVAL_P(const_name), Z_STRLEN_P(const_name))!=0) { + c = NULL; + } + } else { + c = NULL; + } + efree(lookup_name); + } + if (c && (c->flags & CONST_CT_SUBST)) { + zval_dtor(const_name); + result->op_type = IS_CONST; + result->u.constant = c->value; + zval_copy_ctor(&result->u.constant); + INIT_PZVAL(&result->u.constant); + return 1; + } + return 0; +} + void zend_do_fetch_constant(znode *result, znode *constant_container, znode *constant_name, int mode TSRMLS_DC) { switch (mode) { @@ -3102,13 +3129,15 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con if (constant_container) { zend_do_fetch_class_name(NULL, constant_container, constant_name TSRMLS_CC); *result = *constant_container; - } else { + result->u.constant.type = IS_CONSTANT; + } else if (!zend_constant_ct_subst(result, &constant_name->u.constant TSRMLS_CC)) { *result = *constant_name; + result->u.constant.type = IS_CONSTANT; } - result->u.constant.type = IS_CONSTANT; break; case ZEND_RT: - { + if (constant_container || + !zend_constant_ct_subst(result, &constant_name->u.constant TSRMLS_CC)) { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); opline->opcode = ZEND_FETCH_CONSTANT; diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index 0f8e0a41bd..670a76199d 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -114,8 +114,7 @@ void zend_register_standard_constants(TSRMLS_D) { zend_constant c; - c.value.type = IS_BOOL; - c.flags = CONST_PERSISTENT; + c.flags = CONST_PERSISTENT | CONST_CT_SUBST; c.module_number = 0; c.name = zend_strndup(ZEND_STRL("TRUE")); @@ -130,16 +129,18 @@ void zend_register_standard_constants(TSRMLS_D) c.value.type = IS_BOOL; zend_register_constant(&c TSRMLS_CC); + c.name = zend_strndup(ZEND_STRL("NULL")); + c.name_len = sizeof("NULL"); + c.value.type = IS_NULL; + zend_register_constant(&c TSRMLS_CC); + + c.flags = CONST_PERSISTENT; + c.name = zend_strndup(ZEND_STRL("ZEND_THREAD_SAFE")); c.name_len = sizeof("ZEND_THREAD_SAFE"); c.value.value.lval = ZTS_V; c.value.type = IS_BOOL; zend_register_constant(&c TSRMLS_CC); - - c.name = zend_strndup(ZEND_STRL("NULL")); - c.name_len = sizeof("NULL"); - c.value.type = IS_NULL; - zend_register_constant(&c TSRMLS_CC); } } diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h index 1bffa56cef..a0cc2b1bb5 100644 --- a/Zend/zend_constants.h +++ b/Zend/zend_constants.h @@ -26,6 +26,7 @@ #define CONST_CS (1<<0) /* Case Sensitive */ #define CONST_PERSISTENT (1<<1) /* Persistent */ +#define CONST_CT_SUBST (2<<1) /* Allow compile-time substitution */ #define PHP_USER_CONSTANT INT_MAX /* a constant defined in user space */ |