]> granicus.if.org Git - php/commitdiff
Optimized constant lookup
authorDmitry Stogov <dmitry@zend.com>
Thu, 24 Apr 2014 20:56:15 +0000 (00:56 +0400)
committerDmitry Stogov <dmitry@zend.com>
Thu, 24 Apr 2014 20:56:15 +0000 (00:56 +0400)
Zend/zend_ast.c
Zend/zend_builtin_functions.c
Zend/zend_constants.c
Zend/zend_constants.h
Zend/zend_execute_API.c
Zend/zend_ini_parser.y
ext/opcache/Optimizer/pass1_5.c
ext/opcache/zend_persist.c
ext/standard/basic_functions.c

index d0cd7da102f945c1b1d4581d5c48ca7641658607..5babcffe48c6dc04c29b4bc07b6bc38b2b600ce8 100644 (file)
@@ -223,7 +223,7 @@ ZEND_API void zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *s
                        break;
                case ZEND_CONST:
                        ZVAL_DUP(result, &ast->u.val);
-                       if (Z_CONSTANT_P(result)) {
+                       if (Z_OPT_CONSTANT_P(result)) {
                                zval_update_constant_ex(result, (void *) 1, scope TSRMLS_CC);
                        }
                        break;
index 1d066deb417d220d447fed9e1b388e623d15dc24..32bd68e58e4c010acbe89994f3fe21dad6d3ff96 100644 (file)
@@ -729,16 +729,13 @@ repeat:
    Check whether a constant exists */
 ZEND_FUNCTION(defined)
 {
-       char *name;
-       int name_len;
-       zval c;
+       zend_string *name;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &name) == FAILURE) {
                return;
        }
        
-       if (zend_get_constant_ex(name, name_len, &c, NULL, ZEND_FETCH_CLASS_SILENT TSRMLS_CC)) {
-               zval_dtor(&c);
+       if (zend_get_constant_ex(name, NULL, ZEND_FETCH_CLASS_SILENT TSRMLS_CC)) {
                RETURN_TRUE;
        } else {
                RETURN_FALSE;
@@ -927,7 +924,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
 
                /* this is necessary to make it able to work with default array
                 * properties, returned to user */
-               if (Z_CONSTANT(prop_copy)) {
+               if (Z_OPT_CONSTANT(prop_copy)) {
                        zval_update_constant(&prop_copy, 0 TSRMLS_CC);
                }
 
index 72fa9cb1776fe3bc9699bae2bff7f88b8ab15327..fd98a92c4e98994bb07df45bafcbbdaa177a1f1b 100644 (file)
@@ -278,12 +278,14 @@ static zend_constant *zend_get_special_constant(const char *name, uint name_len
 }
 
 
-ZEND_API int zend_get_constant(const char *name, uint name_len, zval *result TSRMLS_DC)
+ZEND_API zval *zend_get_constant_str(const char *name, uint name_len TSRMLS_DC)
 {
        zend_constant *c;
+       ALLOCA_FLAG(use_heap)
 
        if ((c = zend_hash_str_find_ptr(EG(zend_constants), name, name_len)) == NULL) {
-               char *lcname = zend_str_tolower_dup(name, name_len);
+               char *lcname = do_alloca(name_len + 1, use_heap);
+               zend_str_tolower_copy(lcname, name, name_len);
                if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, name_len)) != NULL) {
                        if (c->flags & CONST_CS) {
                                c = NULL;
@@ -291,29 +293,47 @@ ZEND_API int zend_get_constant(const char *name, uint name_len, zval *result TSR
                } else {
                        c = zend_get_special_constant(name, name_len TSRMLS_CC);
                }
-               efree(lcname);
+               free_alloca(lcname, use_heap);
        }
 
-       if (c) {
-               ZVAL_DUP(result, &c->value);
-               return 1;
+       return c ? &c->value : NULL;
+}
+
+ZEND_API zval *zend_get_constant(zend_string *name TSRMLS_DC)
+{
+       zend_constant *c;
+       ALLOCA_FLAG(use_heap)
+
+       if ((c = zend_hash_find_ptr(EG(zend_constants), name)) == NULL) {
+               char *lcname = do_alloca(name->len + 1, use_heap);
+               zend_str_tolower_copy(lcname, name->val, name->len);
+               if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, name->len)) != NULL) {
+                       if (c->flags & CONST_CS) {
+                               c = NULL;
+                       }
+               } else {
+                       c = zend_get_special_constant(name->val, name->len TSRMLS_CC);
+               }
+               free_alloca(lcname, use_heap);
        }
 
-       return 0;
+       return c ? &c->value : NULL;
 }
 
-ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result, zend_class_entry *scope, ulong flags TSRMLS_DC)
+ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope, ulong flags TSRMLS_DC)
 {
        zend_constant *c;
-       int retval = 1;
        const char *colon;
        zend_class_entry *ce = NULL;
        zend_string *class_name;
+       const char *name = cname->val;
+       uint name_len = cname->len;
 
        /* Skip leading \\ */
        if (name[0] == '\\') {
                name += 1;
                name_len -= 1;
+               cname = NULL;
        }
 
        if ((colon = zend_memrchr(name, ':', name_len)) &&
@@ -321,12 +341,13 @@ ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result,
                int class_name_len = colon - name - 1;
                int const_name_len = name_len - class_name_len - 2;
                zend_string *constant_name = STR_INIT(colon + 1, const_name_len, 0);
-               zend_string *lcname;
+               char *lcname;
                zval *ret_constant = NULL;
+               ALLOCA_FLAG(use_heap)
 
                class_name = STR_INIT(name, class_name_len, 0);
-               lcname = STR_ALLOC(class_name_len, 0);
-               zend_str_tolower_copy(lcname->val, name, class_name_len);
+               lcname = do_alloca(class_name_len + 1, use_heap);
+               zend_str_tolower_copy(lcname, name, class_name_len);
                if (!scope) {
                        if (EG(in_execution)) {
                                scope = EG(scope);
@@ -336,16 +357,14 @@ ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result,
                }
 
                if (class_name_len == sizeof("self")-1 &&
-                   !memcmp(lcname->val, "self", sizeof("self")-1)) {
+                   !memcmp(lcname, "self", sizeof("self")-1)) {
                        if (scope) {
                                ce = scope;
                        } else {
                                zend_error(E_ERROR, "Cannot access self:: when no class scope is active");
-                               retval = 0;
                        }
-                       STR_FREE(lcname);
                } else if (class_name_len == sizeof("parent")-1 &&
-                          !memcmp(lcname->val, "parent", sizeof("parent")-1)) {
+                          !memcmp(lcname, "parent", sizeof("parent")-1)) {
                        if (!scope) {
                                zend_error(E_ERROR, "Cannot access parent:: when no class scope is active");
                        } else if (!scope->parent) {
@@ -353,38 +372,33 @@ ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result,
                        } else {
                                ce = scope->parent;
                        }
-                       STR_FREE(lcname);
                } else if (class_name_len == sizeof("static")-1 &&
-                          !memcmp(lcname->val, "static", sizeof("static")-1)) {
+                          !memcmp(lcname, "static", sizeof("static")-1)) {
                        if (EG(called_scope)) {
                                ce = EG(called_scope);
                        } else {
                                zend_error(E_ERROR, "Cannot access static:: when no class scope is active");
                        }
-                       STR_FREE(lcname);
                } else {
-                       STR_FREE(lcname);
                        ce = zend_fetch_class(class_name, flags TSRMLS_CC);
                }
-               if (retval && ce) {
-                       if ((ret_constant = zend_hash_find(&ce->constants_table, constant_name)) == NULL) {
-                               retval = 0;
+               free_alloca(lcname, use_heap);
+               if (ce) {
+                       ret_constant = zend_hash_find(&ce->constants_table, constant_name);
+                       if (ret_constant == NULL) {
                                if ((flags & ZEND_FETCH_CLASS_SILENT) == 0) {
                                        zend_error(E_ERROR, "Undefined class constant '%s::%s'", class_name->val, constant_name->val);
                                }
                        } else if (Z_ISREF_P(ret_constant)) {
                                ret_constant = Z_REFVAL_P(ret_constant);
                        }
-               } else if (!ce) {
-                       retval = 0;
                }
                STR_FREE(class_name);
                STR_FREE(constant_name);
-               if (retval) {
+               if (ret_constant && Z_CONSTANT_P(ret_constant)) {
                        zval_update_constant_ex(ret_constant, (void*)1, ce TSRMLS_CC);
-                       ZVAL_DUP(result, ret_constant);
                }
-               return retval;
+               return ret_constant;
        }
 
        /* non-class constant */
@@ -393,45 +407,43 @@ ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result,
                int prefix_len = colon - name;
                int const_name_len = name_len - prefix_len - 1;
                const char *constant_name = colon + 1;
-               zend_string *lcname;
-               int found_const = 0;
+               char *lcname;
+               int lcname_len;
+               ALLOCA_FLAG(use_heap)
 
-               lcname = STR_ALLOC(prefix_len + 1 + const_name_len, 0);
-               zend_str_tolower_copy(lcname->val, name, prefix_len);
+               lcname_len = prefix_len + 1 + const_name_len;
+               lcname = do_alloca(lcname_len + 1, use_heap);
+               zend_str_tolower_copy(lcname, name, prefix_len);
                /* Check for namespace constant */
 
-               lcname->val[prefix_len] = '\\';
-               memcpy(lcname->val + prefix_len + 1, constant_name, const_name_len + 1);
+               lcname[prefix_len] = '\\';
+               memcpy(lcname + prefix_len + 1, constant_name, const_name_len + 1);
 
-               if ((c = zend_hash_find_ptr(EG(zend_constants), lcname)) != NULL) {
-                       found_const = 1;
-               } else {
+               if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len)) == NULL) {
                        /* try lowercase */
-                       zend_str_tolower(lcname->val + prefix_len + 1, const_name_len);
-                       STR_FORGET_HASH_VAL(lcname);
-                       if ((c = zend_hash_find_ptr(EG(zend_constants), lcname)) != NULL) {
-                               if ((c->flags & CONST_CS) == 0) {
-                                       found_const = 1;
+                       zend_str_tolower(lcname + prefix_len + 1, const_name_len);
+                       if ((c = zend_hash_str_find_ptr(EG(zend_constants), lcname, lcname_len)) != NULL) {
+                               if ((c->flags & CONST_CS) != 0) {
+                                       c = NULL;
                                }
                        }
                }
-               STR_FREE(lcname);
-               if (found_const) {
-                       ZVAL_COPY_VALUE(result, &c->value);
-                       zval_update_constant_ex(result, (void*)1, NULL TSRMLS_CC);
-                       zval_copy_ctor(result);
-                       return 1;
+               free_alloca(lcname, use_heap);
+               if (c) {
+                       return &c->value;
                }
                /* name requires runtime resolution, need to check non-namespaced name */
                if ((flags & IS_CONSTANT_UNQUALIFIED) != 0) {
-                       name = constant_name;
-                       name_len = const_name_len;
-                       return zend_get_constant(name, name_len, result TSRMLS_CC);
+                       return zend_get_constant_str(constant_name, const_name_len TSRMLS_CC);
                }
-               return 0;
+               return NULL;
        }
 
-       return zend_get_constant(name, name_len, result TSRMLS_CC);
+       if (cname) {
+               return zend_get_constant(cname TSRMLS_CC);
+       } else {
+               return zend_get_constant_str(name, name_len TSRMLS_CC);
+       }
 }
 
 zend_constant *zend_quick_get_constant(const zval *key, ulong flags TSRMLS_DC)
index df7f27cf8f71908b7e510106a25275e514d9bba3..09a5dac63de7cbafbc997f8aadbb0c749ff4574d 100644 (file)
@@ -65,8 +65,9 @@ int zend_startup_constants(TSRMLS_D);
 int zend_shutdown_constants(TSRMLS_D);
 void zend_register_standard_constants(TSRMLS_D);
 void clean_non_persistent_constants(TSRMLS_D);
-ZEND_API int zend_get_constant(const char *name, uint name_len, zval *result TSRMLS_DC);
-ZEND_API int zend_get_constant_ex(const char *name, uint name_len, zval *result, zend_class_entry *scope, ulong flags TSRMLS_DC);
+ZEND_API zval *zend_get_constant(zend_string *name TSRMLS_DC);
+ZEND_API zval *zend_get_constant_str(const char *name, uint name_len TSRMLS_DC);
+ZEND_API zval *zend_get_constant_ex(zend_string *name, zend_class_entry *scope, ulong flags TSRMLS_DC);
 ZEND_API void zend_register_bool_constant(const char *name, uint name_len, zend_bool bval, int flags, int module_number TSRMLS_DC);
 ZEND_API void zend_register_null_constant(const char *name, uint name_len, int flags, int module_number TSRMLS_DC);
 ZEND_API void zend_register_long_constant(const char *name, uint name_len, long lval, int flags, int module_number TSRMLS_DC);
index d2fefa7f711c9ff2f58b91ea81e0895445e307c5..3ad4a8cac1ccddd127d7a27558d4accac46994f4 100644 (file)
@@ -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;
 }
index b65b16a93c8b31d56b77da82218da65b4d7424b2..29a2cb0aff9bb045ad179cf3778b961c5adbd662 100644 (file)
@@ -112,15 +112,24 @@ static void zend_ini_add_string(zval *result, zval *op1, zval *op2)
 */
 static void zend_ini_get_constant(zval *result, zval *name TSRMLS_DC)
 {
-       zval z_constant;
+       zval *c, tmp;
 
        /* If name contains ':' it is not a constant. Bug #26893. */
        if (!memchr(Z_STRVAL_P(name), ':', Z_STRLEN_P(name))
-                       && zend_get_constant(Z_STRVAL_P(name), Z_STRLEN_P(name), &z_constant TSRMLS_CC)) {
-               /* z_constant is emalloc()'d */
-               convert_to_string(&z_constant);
-               ZVAL_PSTRINGL(result, Z_STRVAL(z_constant), Z_STRLEN(z_constant));
-               zval_dtor(&z_constant);
+                       && (c = zend_get_constant(Z_STR_P(name) TSRMLS_CC)) != 0) {
+               if (Z_TYPE_P(c) != IS_STRING) {
+                       ZVAL_COPY_VALUE(&tmp, c);
+                       if (Z_OPT_CONSTANT(tmp)) {
+                               zval_update_constant_ex(&tmp, (void*)1, NULL TSRMLS_CC);
+                       }
+                       zval_opt_copy_ctor(&tmp);
+                       convert_to_string(&tmp);
+                       c = &tmp;
+               }
+               ZVAL_PSTRINGL(result, Z_STRVAL_P(c), Z_STRLEN_P(c));
+               if (c == &tmp) {
+                       zval_dtor(&tmp);
+               }
                STR_FREE(Z_STR_P(name));
        } else {
                *result = *name;
index 4e1410a76ef5a1c8c1180e43daced09872e140d2..cae7e80375a76ac5b94a75c1c97f1e9bb4d2f2c4 100644 (file)
@@ -218,16 +218,16 @@ if (ZEND_OPTIMIZER_PASS_1 & OPTIMIZATION_LEVEL) {
                                /* substitute __COMPILER_HALT_OFFSET__ constant */
                                zend_bool orig_in_execution = EG(in_execution);
                                zend_op_array *orig_op_array = EG(active_op_array);
-                               zval offset;
+                               zval *offset;
 
                                EG(in_execution) = 1;
                                EG(active_op_array) = op_array;
-                               if (zend_get_constant("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1, &offset TSRMLS_CC)) {
+                               if ((offset = zend_get_constant_str("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1 TSRMLS_CC)) != NULL) {
                                        zend_uint tv = ZEND_RESULT(opline).var;
 
                                        literal_dtor(&ZEND_OP2_LITERAL(opline));
                                        MAKE_NOP(opline);
-                                       replace_tmp_by_const(op_array, opline, tv, &offset TSRMLS_CC);
+                                       replace_tmp_by_const(op_array, opline, tv, offset TSRMLS_CC);
                                }
                                EG(active_op_array) = orig_op_array;
                                EG(in_execution) = orig_in_execution;
index 39a2aa4a7ce1e3c4f15f561a5a974e4b328b2a0e..bc63705e5e014f8763f885a8983be8ee32ef8d5f 100644 (file)
@@ -198,15 +198,15 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
        if (main_persistent_script) {
                zend_bool orig_in_execution = EG(in_execution);
                zend_op_array *orig_op_array = EG(active_op_array);
-               zval offset;
+               zval *offset;
 
 #if ZEND_EXTENSION_API_NO < PHP_5_3_X_API_NO
                main_persistent_script->early_binding = -1;
 #endif
                EG(in_execution) = 1;
                EG(active_op_array) = op_array;
-               if (zend_get_constant("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1, &offset TSRMLS_CC)) {
-                       main_persistent_script->compiler_halt_offset = Z_LVAL(offset);
+               if ((offset = zend_get_constant_str("__COMPILER_HALT_OFFSET__", sizeof("__COMPILER_HALT_OFFSET__") - 1 TSRMLS_CC)) != NULL) {
+                       main_persistent_script->compiler_halt_offset = Z_LVAL_P(offset);
                }
                EG(active_op_array) = orig_op_array;
                EG(in_execution) = orig_in_execution;
index 7647781e2ba2346037b875010c67d4cd062e12af..0393917e23bd5c5f95d4dc651626c1f8c67dc849 100644 (file)
@@ -3854,15 +3854,22 @@ PHP_MINFO_FUNCTION(basic) /* {{{ */
    Given the name of a constant this function will return the constant's associated value */
 PHP_FUNCTION(constant)
 {
-       char *const_name;
-       int const_name_len;
+       zend_string *const_name;
+       zval *c;
 
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &const_name, &const_name_len) == FAILURE) {
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &const_name) == FAILURE) {
                return;
        }
 
-       if (!zend_get_constant_ex(const_name, const_name_len, return_value, NULL, ZEND_FETCH_CLASS_SILENT TSRMLS_CC)) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't find constant %s", const_name);
+       c = zend_get_constant_ex(const_name, NULL, ZEND_FETCH_CLASS_SILENT TSRMLS_CC);
+       if (c) {
+               ZVAL_COPY_VALUE(return_value, c);
+               if (Z_CONSTANT_P(return_value)) {
+                       zval_update_constant_ex(return_value, (void*)1, NULL TSRMLS_CC);
+               }
+               zval_copy_ctor(return_value);
+       } else {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Couldn't find constant %s", const_name->val);
                RETURN_NULL();
        }
 }