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;
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;
/* 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);
}
}
-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;
} 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)) &&
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);
}
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) {
} 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 */
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)
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);
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)) {
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)))) {
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);
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;
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) {
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);
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;
}
*/
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;
/* 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;
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;
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();
}
}