mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Refactor class name resolution as well
This commit is contained in:
parent
b3336270f6
commit
17c2d16d79
3 changed files with 72 additions and 77 deletions
|
@ -1651,7 +1651,7 @@ void zend_do_receive_param(zend_uchar op, znode *varname, znode *initialization,
|
||||||
} else {
|
} else {
|
||||||
cur_arg_info->type_hint = IS_OBJECT;
|
cur_arg_info->type_hint = IS_OBJECT;
|
||||||
if (ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_type->u.constant), Z_STRLEN(class_type->u.constant))) {
|
if (ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_type->u.constant), Z_STRLEN(class_type->u.constant))) {
|
||||||
zend_resolve_class_name(class_type TSRMLS_CC);
|
zend_resolve_class_name_old(class_type TSRMLS_CC);
|
||||||
}
|
}
|
||||||
Z_STR(class_type->u.constant) = zend_new_interned_string(Z_STR(class_type->u.constant) TSRMLS_CC);
|
Z_STR(class_type->u.constant) = zend_new_interned_string(Z_STR(class_type->u.constant) TSRMLS_CC);
|
||||||
if (IS_INTERNED(Z_STR(class_type->u.constant))) {
|
if (IS_INTERNED(Z_STR(class_type->u.constant))) {
|
||||||
|
@ -1777,77 +1777,70 @@ zend_string *zend_resolve_const_name(
|
||||||
name, is_fully_qualified, 1, CG(current_import_const) TSRMLS_CC);
|
name, is_fully_qualified, 1, CG(current_import_const) TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
|
||||||
void zend_resolve_class_name(znode *class_name TSRMLS_DC) /* {{{ */
|
zend_string *zend_resolve_class_name(
|
||||||
{
|
zend_string *name, zend_bool is_fully_qualified TSRMLS_DC
|
||||||
|
) {
|
||||||
char *compound;
|
char *compound;
|
||||||
zend_string *lcname;
|
|
||||||
zval *ns;
|
zval *ns;
|
||||||
znode tmp;
|
|
||||||
int len;
|
|
||||||
|
|
||||||
compound = memchr(Z_STRVAL(class_name->u.constant), '\\', Z_STRLEN(class_name->u.constant));
|
if (is_fully_qualified || name->val[0] == '\\') {
|
||||||
if (compound) {
|
/* Remove \ prefix (only relevant if this is a string rather than a label) */
|
||||||
/* This is a compound class name that contains namespace prefix */
|
if (name->val[0] == '\\') {
|
||||||
if (Z_STRVAL(class_name->u.constant)[0] == '\\') {
|
name = STR_INIT(name->val + 1, name->len - 1, 0);
|
||||||
/* The STRING name has "\" prefix */
|
} else {
|
||||||
memmove(Z_STRVAL(class_name->u.constant), Z_STRVAL(class_name->u.constant)+1, Z_STRLEN(class_name->u.constant));
|
STR_ADDREF(name);
|
||||||
Z_STR(class_name->u.constant) = STR_REALLOC(
|
}
|
||||||
Z_STR(class_name->u.constant),
|
/* Ensure that \self, \parent and \static are not used */
|
||||||
Z_STRLEN(class_name->u.constant) - 1, 0);
|
if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(name->val, name->len)) {
|
||||||
Z_TYPE_FLAGS(class_name->u.constant) = IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE;
|
zend_error_noreturn(E_COMPILE_ERROR, "'\\%s' is an invalid class name", name->val);
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
if (ZEND_FETCH_CLASS_DEFAULT != zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant))) {
|
if (CG(current_import)) {
|
||||||
zend_error_noreturn(E_COMPILE_ERROR, "'\\%s' is an invalid class name", Z_STRVAL(class_name->u.constant));
|
compound = memchr(name->val, '\\', name->len);
|
||||||
|
if (compound) {
|
||||||
|
/* If the first part of a qualified name is an alias, substitute it. */
|
||||||
|
size_t len = compound - name->val;
|
||||||
|
zend_string *lcname = STR_ALLOC(len, 0);
|
||||||
|
zend_str_tolower_copy(lcname->val, name->val, len);
|
||||||
|
|
||||||
|
ns = zend_hash_find(CG(current_import), lcname);
|
||||||
|
STR_FREE(lcname);
|
||||||
|
|
||||||
|
if (ns) {
|
||||||
|
return zend_concat_names(
|
||||||
|
Z_STRVAL_P(ns), Z_STRLEN_P(ns), name->val + len + 1, name->len - len - 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (CG(current_import)) {
|
/* If an unqualified name is an alias, replace it. */
|
||||||
len = compound - Z_STRVAL(class_name->u.constant);
|
zend_string *lcname = STR_ALLOC(name->len, 0);
|
||||||
lcname = STR_ALLOC(len, 0);
|
zend_str_tolower_copy(lcname->val, name->val, name->len);
|
||||||
zend_str_tolower_copy(lcname->val, Z_STRVAL(class_name->u.constant), len);
|
|
||||||
/* Check if first part of compound name is an import name */
|
|
||||||
if ((ns = zend_hash_find(CG(current_import), lcname)) != NULL) {
|
|
||||||
/* Substitute import name */
|
|
||||||
tmp.op_type = IS_CONST;
|
|
||||||
ZVAL_DUP(&tmp.u.constant, ns);
|
|
||||||
len += 1;
|
|
||||||
Z_STRLEN(class_name->u.constant) -= len;
|
|
||||||
memmove(Z_STRVAL(class_name->u.constant), Z_STRVAL(class_name->u.constant)+len, Z_STRLEN(class_name->u.constant)+1);
|
|
||||||
zend_do_build_namespace_name(&tmp, &tmp, class_name TSRMLS_CC);
|
|
||||||
*class_name = tmp;
|
|
||||||
STR_FREE(lcname);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
STR_FREE(lcname);
|
|
||||||
}
|
|
||||||
/* Here name is not prefixed with \ and not imported */
|
|
||||||
if (Z_TYPE(CG(current_namespace)) != IS_UNDEF) {
|
|
||||||
tmp.op_type = IS_CONST;
|
|
||||||
ZVAL_DUP(&tmp.u.constant, &CG(current_namespace));
|
|
||||||
zend_do_build_namespace_name(&tmp, &tmp, class_name TSRMLS_CC);
|
|
||||||
*class_name = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (CG(current_import) || Z_TYPE(CG(current_namespace)) != IS_UNDEF) {
|
|
||||||
/* this is a plain name (without \) */
|
|
||||||
lcname = STR_ALLOC(Z_STRLEN(class_name->u.constant), 0);
|
|
||||||
zend_str_tolower_copy(lcname->val, Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant));
|
|
||||||
|
|
||||||
if (CG(current_import) &&
|
ns = zend_hash_find(CG(current_import), lcname);
|
||||||
(ns = zend_hash_find(CG(current_import), lcname)) != NULL) {
|
STR_FREE(lcname);
|
||||||
/* The given name is an import name. Substitute it. */
|
|
||||||
zval_dtor(&class_name->u.constant);
|
if (ns) {
|
||||||
ZVAL_DUP(&class_name->u.constant, ns);
|
return STR_COPY(Z_STR_P(ns));
|
||||||
} else if (Z_TYPE(CG(current_namespace)) != IS_UNDEF) {
|
}
|
||||||
/* plain name, no import - prepend current namespace to it */
|
|
||||||
tmp.op_type = IS_CONST;
|
|
||||||
ZVAL_DUP(&tmp.u.constant, &CG(current_namespace));
|
|
||||||
zend_do_build_namespace_name(&tmp, &tmp, class_name TSRMLS_CC);
|
|
||||||
*class_name = tmp;
|
|
||||||
}
|
}
|
||||||
STR_FREE(lcname);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If not fully qualified and not an alias, prepend the current namespace */
|
||||||
|
if (Z_TYPE(CG(current_namespace)) != IS_UNDEF) {
|
||||||
|
return zend_concat_names(
|
||||||
|
Z_STRVAL(CG(current_namespace)), Z_STRLEN(CG(current_namespace)), name->val, name->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return STR_COPY(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void zend_resolve_class_name_old(znode *class_name TSRMLS_DC) {
|
||||||
|
zend_string *resolved_name = zend_resolve_class_name(
|
||||||
|
Z_STR(class_name->u.constant), 0 TSRMLS_CC);
|
||||||
|
zval_dtor(&class_name->u.constant);
|
||||||
|
ZVAL_STR(&class_name->u.constant, resolved_name);
|
||||||
}
|
}
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC) /* {{{ */
|
void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC) /* {{{ */
|
||||||
{
|
{
|
||||||
|
@ -1874,7 +1867,7 @@ void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC) /* {{{ */
|
||||||
zval_dtor(&class_name->u.constant);
|
zval_dtor(&class_name->u.constant);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
zend_resolve_class_name(class_name TSRMLS_CC);
|
zend_resolve_class_name_old(class_name TSRMLS_CC);
|
||||||
opline->op2_type = IS_CONST;
|
opline->op2_type = IS_CONST;
|
||||||
opline->op2.constant =
|
opline->op2.constant =
|
||||||
zend_add_class_name_literal(CG(active_op_array), &class_name->u.constant TSRMLS_CC);
|
zend_add_class_name_literal(CG(active_op_array), &class_name->u.constant TSRMLS_CC);
|
||||||
|
@ -2280,7 +2273,7 @@ void zend_do_begin_catch(znode *catch_token, znode *class_name, znode *catch_var
|
||||||
|
|
||||||
if (class_name->op_type == IS_CONST &&
|
if (class_name->op_type == IS_CONST &&
|
||||||
ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant))) {
|
ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_name->u.constant), Z_STRLEN(class_name->u.constant))) {
|
||||||
zend_resolve_class_name(class_name TSRMLS_CC);
|
zend_resolve_class_name_old(class_name TSRMLS_CC);
|
||||||
catch_class = *class_name;
|
catch_class = *class_name;
|
||||||
} else {
|
} else {
|
||||||
zend_error_noreturn(E_COMPILE_ERROR, "Bad class name in the catch statement");
|
zend_error_noreturn(E_COMPILE_ERROR, "Bad class name in the catch statement");
|
||||||
|
@ -3952,7 +3945,7 @@ void zend_prepare_reference(znode *result, znode *class_name, znode *method_name
|
||||||
/* REM: There should not be a need for copying,
|
/* REM: There should not be a need for copying,
|
||||||
zend_do_begin_class_declaration is also just using that string */
|
zend_do_begin_class_declaration is also just using that string */
|
||||||
if (class_name) {
|
if (class_name) {
|
||||||
zend_resolve_class_name(class_name TSRMLS_CC);
|
zend_resolve_class_name_old(class_name TSRMLS_CC);
|
||||||
method_ref->class_name = Z_STR(class_name->u.constant);
|
method_ref->class_name = Z_STR(class_name->u.constant);
|
||||||
} else {
|
} else {
|
||||||
method_ref->class_name = NULL;
|
method_ref->class_name = NULL;
|
||||||
|
@ -4564,7 +4557,7 @@ void zend_do_implements_interface(znode *interface_name TSRMLS_DC) /* {{{ */
|
||||||
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||||
opline->opcode = ZEND_ADD_INTERFACE;
|
opline->opcode = ZEND_ADD_INTERFACE;
|
||||||
SET_NODE(opline->op1, &CG(implementing_class));
|
SET_NODE(opline->op1, &CG(implementing_class));
|
||||||
zend_resolve_class_name(interface_name TSRMLS_CC);
|
zend_resolve_class_name_old(interface_name TSRMLS_CC);
|
||||||
opline->extended_value = (opline->extended_value & ~ZEND_FETCH_CLASS_MASK) | ZEND_FETCH_CLASS_INTERFACE;
|
opline->extended_value = (opline->extended_value & ~ZEND_FETCH_CLASS_MASK) | ZEND_FETCH_CLASS_INTERFACE;
|
||||||
opline->op2_type = IS_CONST;
|
opline->op2_type = IS_CONST;
|
||||||
opline->op2.constant = zend_add_class_name_literal(CG(active_op_array), &interface_name->u.constant TSRMLS_CC);
|
opline->op2.constant = zend_add_class_name_literal(CG(active_op_array), &interface_name->u.constant TSRMLS_CC);
|
||||||
|
@ -4596,7 +4589,7 @@ void zend_do_use_trait(znode *trait_name TSRMLS_DC) /* {{{ */
|
||||||
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||||
opline->opcode = ZEND_ADD_TRAIT;
|
opline->opcode = ZEND_ADD_TRAIT;
|
||||||
SET_NODE(opline->op1, &CG(implementing_class));
|
SET_NODE(opline->op1, &CG(implementing_class));
|
||||||
zend_resolve_class_name(trait_name TSRMLS_CC);
|
zend_resolve_class_name_old(trait_name TSRMLS_CC);
|
||||||
opline->extended_value = ZEND_FETCH_CLASS_TRAIT;
|
opline->extended_value = ZEND_FETCH_CLASS_TRAIT;
|
||||||
opline->op2_type = IS_CONST;
|
opline->op2_type = IS_CONST;
|
||||||
opline->op2.constant = zend_add_class_name_literal(CG(active_op_array), &trait_name->u.constant TSRMLS_CC);
|
opline->op2.constant = zend_add_class_name_literal(CG(active_op_array), &trait_name->u.constant TSRMLS_CC);
|
||||||
|
@ -6147,7 +6140,7 @@ static zend_op *zend_compile_class_ref(znode *result, zend_ast *name_ast TSRMLS_
|
||||||
zval_ptr_dtor(name);
|
zval_ptr_dtor(name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
zend_resolve_class_name(&name_node TSRMLS_CC);
|
zend_resolve_class_name_old(&name_node TSRMLS_CC);
|
||||||
opline->op2_type = IS_CONST;
|
opline->op2_type = IS_CONST;
|
||||||
opline->op2.constant =
|
opline->op2.constant =
|
||||||
zend_add_class_name_literal(CG(active_op_array), name TSRMLS_CC);
|
zend_add_class_name_literal(CG(active_op_array), name TSRMLS_CC);
|
||||||
|
@ -6307,7 +6300,7 @@ zend_op *zend_compile_static_prop_common(znode *result, zend_ast *ast, int type
|
||||||
|
|
||||||
if (zend_is_const_default_class_ref(class_ast)) {
|
if (zend_is_const_default_class_ref(class_ast)) {
|
||||||
zend_compile_expr(&class_node, class_ast TSRMLS_CC);
|
zend_compile_expr(&class_node, class_ast TSRMLS_CC);
|
||||||
zend_resolve_class_name(&class_node TSRMLS_CC);
|
zend_resolve_class_name_old(&class_node TSRMLS_CC);
|
||||||
} else {
|
} else {
|
||||||
zend_compile_class_ref(&class_node, class_ast TSRMLS_CC);
|
zend_compile_class_ref(&class_node, class_ast TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
@ -6828,7 +6821,7 @@ void zend_compile_static_call(znode *result, zend_ast *ast, int type TSRMLS_DC)
|
||||||
|
|
||||||
if (zend_is_const_default_class_ref(class_ast)) {
|
if (zend_is_const_default_class_ref(class_ast)) {
|
||||||
zend_compile_expr(&class_node, class_ast TSRMLS_CC);
|
zend_compile_expr(&class_node, class_ast TSRMLS_CC);
|
||||||
zend_resolve_class_name(&class_node TSRMLS_CC);
|
zend_resolve_class_name_old(&class_node TSRMLS_CC);
|
||||||
} else {
|
} else {
|
||||||
opline = zend_compile_class_ref(&class_node, class_ast TSRMLS_CC);
|
opline = zend_compile_class_ref(&class_node, class_ast TSRMLS_CC);
|
||||||
extended_value = opline->extended_value;
|
extended_value = opline->extended_value;
|
||||||
|
@ -7447,7 +7440,7 @@ void zend_compile_class_const(znode *result, zend_ast *ast TSRMLS_DC) {
|
||||||
|
|
||||||
if (zend_is_const_default_class_ref(class_ast)) {
|
if (zend_is_const_default_class_ref(class_ast)) {
|
||||||
zend_compile_expr(&class_node, class_ast TSRMLS_CC);
|
zend_compile_expr(&class_node, class_ast TSRMLS_CC);
|
||||||
zend_resolve_class_name(&class_node TSRMLS_CC);
|
zend_resolve_class_name_old(&class_node TSRMLS_CC);
|
||||||
} else {
|
} else {
|
||||||
zend_compile_class_ref(&class_node, class_ast TSRMLS_CC);
|
zend_compile_class_ref(&class_node, class_ast TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
@ -7502,7 +7495,7 @@ void zend_compile_resolve_class_name(znode *result, zend_ast *ast TSRMLS_DC) {
|
||||||
break;
|
break;
|
||||||
case ZEND_FETCH_CLASS_DEFAULT:
|
case ZEND_FETCH_CLASS_DEFAULT:
|
||||||
zend_compile_expr(result, name_ast TSRMLS_CC);
|
zend_compile_expr(result, name_ast TSRMLS_CC);
|
||||||
zend_resolve_class_name(result TSRMLS_CC);
|
zend_resolve_class_name_old(result TSRMLS_CC);
|
||||||
break;
|
break;
|
||||||
EMPTY_SWITCH_DEFAULT_CASE()
|
EMPTY_SWITCH_DEFAULT_CASE()
|
||||||
}
|
}
|
||||||
|
@ -7592,7 +7585,7 @@ void zend_compile_const_expr_class_const(zend_ast **ast_ptr TSRMLS_DC) {
|
||||||
zend_error_noreturn(E_COMPILE_ERROR,
|
zend_error_noreturn(E_COMPILE_ERROR,
|
||||||
"\"static::\" is not allowed in compile-time constants");
|
"\"static::\" is not allowed in compile-time constants");
|
||||||
} else if (ZEND_FETCH_CLASS_DEFAULT == fetch_type) {
|
} else if (ZEND_FETCH_CLASS_DEFAULT == fetch_type) {
|
||||||
zend_resolve_class_name(&class_name TSRMLS_CC);
|
zend_resolve_class_name_old(&class_name TSRMLS_CC);
|
||||||
}
|
}
|
||||||
|
|
||||||
zend_do_build_full_name(NULL, &class_name, &const_name, 1 TSRMLS_CC);
|
zend_do_build_full_name(NULL, &class_name, &const_name, 1 TSRMLS_CC);
|
||||||
|
@ -7659,7 +7652,7 @@ void zend_compile_const_expr_resolve_class_name(zend_ast **ast_ptr TSRMLS_DC) {
|
||||||
break;
|
break;
|
||||||
case ZEND_FETCH_CLASS_DEFAULT:
|
case ZEND_FETCH_CLASS_DEFAULT:
|
||||||
zend_compile_expr(&result, name_ast TSRMLS_CC);
|
zend_compile_expr(&result, name_ast TSRMLS_CC);
|
||||||
zend_resolve_class_name(&result TSRMLS_CC);
|
zend_resolve_class_name_old(&result TSRMLS_CC);
|
||||||
break;
|
break;
|
||||||
EMPTY_SWITCH_DEFAULT_CASE()
|
EMPTY_SWITCH_DEFAULT_CASE()
|
||||||
}
|
}
|
||||||
|
|
|
@ -459,9 +459,11 @@ ZEND_API size_t zend_get_scanned_file_offset(TSRMLS_D);
|
||||||
zend_string *zend_resolve_non_class_name(zend_string *name, zend_bool *is_fully_qualified, zend_bool case_sensitive, HashTable *current_import_sub TSRMLS_DC);
|
zend_string *zend_resolve_non_class_name(zend_string *name, zend_bool *is_fully_qualified, zend_bool case_sensitive, HashTable *current_import_sub TSRMLS_DC);
|
||||||
zend_string *zend_resolve_function_name(zend_string *name, zend_bool *is_fully_qualified TSRMLS_DC);
|
zend_string *zend_resolve_function_name(zend_string *name, zend_bool *is_fully_qualified TSRMLS_DC);
|
||||||
zend_string *zend_resolve_const_name(zend_string *name, zend_bool *is_fully_qualified TSRMLS_DC);
|
zend_string *zend_resolve_const_name(zend_string *name, zend_bool *is_fully_qualified TSRMLS_DC);
|
||||||
void zend_resolve_class_name(znode *class_name TSRMLS_DC);
|
zend_string *zend_resolve_class_name(zend_string *name, zend_bool is_fully_qualified TSRMLS_DC);
|
||||||
ZEND_API zend_string *zend_get_compiled_variable_name(const zend_op_array *op_array, zend_uint var);
|
ZEND_API zend_string *zend_get_compiled_variable_name(const zend_op_array *op_array, zend_uint var);
|
||||||
|
|
||||||
|
void zend_resolve_class_name_old(znode *class_name TSRMLS_DC);
|
||||||
|
|
||||||
#ifdef ZTS
|
#ifdef ZTS
|
||||||
const char *zend_get_zendtext(TSRMLS_D);
|
const char *zend_get_zendtext(TSRMLS_D);
|
||||||
int zend_get_zendleng(TSRMLS_D);
|
int zend_get_zendleng(TSRMLS_D);
|
||||||
|
|
|
@ -676,8 +676,8 @@ trait_precedence:
|
||||||
;
|
;
|
||||||
|
|
||||||
trait_reference_list:
|
trait_reference_list:
|
||||||
fully_qualified_class_name { zend_resolve_class_name(&$1 TSRMLS_CC); zend_init_list(&$$.u.op.ptr, Z_STR($1.u.constant) TSRMLS_CC); }
|
fully_qualified_class_name { zend_resolve_class_name_old(&$1 TSRMLS_CC); zend_init_list(&$$.u.op.ptr, Z_STR($1.u.constant) TSRMLS_CC); }
|
||||||
| trait_reference_list ',' fully_qualified_class_name { zend_resolve_class_name(&$3 TSRMLS_CC); zend_add_to_list(&$1.u.op.ptr, Z_STR($3.u.constant) TSRMLS_CC); $$ = $1; }
|
| trait_reference_list ',' fully_qualified_class_name { zend_resolve_class_name_old(&$3 TSRMLS_CC); zend_add_to_list(&$1.u.op.ptr, Z_STR($3.u.constant) TSRMLS_CC); $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
trait_method_reference:
|
trait_method_reference:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue