From: Julien Pauli Date: Fri, 28 Nov 2014 12:31:53 +0000 (+0100) Subject: Merge branch 'PHP-5.6' X-Git-Tag: PRE_NATIVE_TLS_MERGE~121 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=96f2265d583310bcd9782d97460ba73cd64367f6;p=php Merge branch 'PHP-5.6' * PHP-5.6: updated NEWS updated NEWS Fix #65419 - Inside trait, self::class != __CLASS__ Conflicts: Zend/zend_compile.c --- 96f2265d583310bcd9782d97460ba73cd64367f6 diff --cc Zend/zend_compile.c index 77f1722117,03149091fb..5dbb41f94d --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@@ -5680,75 -7122,86 +5680,88 @@@ void zend_compile_const(znode *result, } /* }}} */ -void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{{ */ +void zend_compile_class_const(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */ { - char *lcname; - zval *name, *ns, tmp; - zend_bool warn = 0; - zend_class_entry **pce; + zend_ast *class_ast = ast->child[0]; + zend_ast *const_ast = ast->child[1]; - if (!CG(current_import)) { - CG(current_import) = emalloc(sizeof(HashTable)); - zend_hash_init(CG(current_import), 0, NULL, ZVAL_PTR_DTOR, 0); - } + znode class_node, const_node; + zend_op *opline; - MAKE_STD_ZVAL(ns); - ZVAL_ZVAL(ns, &ns_name->u.constant, 0, 0); - if (new_name) { - name = &new_name->u.constant; + if (zend_is_const_default_class_ref(class_ast)) { + class_node.op_type = IS_CONST; + ZVAL_STR(&class_node.u.constant, zend_resolve_class_name_ast(class_ast TSRMLS_CC)); } else { - const char *p; - - /* The form "use A\B" is eqivalent to "use A\B as B". - So we extract the last part of compound name to use as a new_name */ - name = &tmp; - p = zend_memrchr(Z_STRVAL_P(ns), '\\', Z_STRLEN_P(ns)); - if (p) { - ZVAL_STRING(name, p+1, 1); - } else { - ZVAL_ZVAL(name, ns, 1, 0); - warn = !is_global && !CG(current_namespace); - } + zend_compile_class_ref(&class_node, class_ast TSRMLS_CC); } - lcname = zend_str_tolower_dup(Z_STRVAL_P(name), Z_STRLEN_P(name)); + zend_compile_expr(&const_node, const_ast TSRMLS_CC); - if (((Z_STRLEN_P(name) == sizeof("self")-1) && - !memcmp(lcname, "self", sizeof("self")-1)) || - ((Z_STRLEN_P(name) == sizeof("parent")-1) && - !memcmp(lcname, "parent", sizeof("parent")-1))) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because '%s' is a special class name", Z_STRVAL_P(ns), Z_STRVAL_P(name), Z_STRVAL_P(name)); + opline = zend_emit_op_tmp(result, ZEND_FETCH_CONSTANT, NULL, &const_node TSRMLS_CC); + + zend_set_class_name_op1(opline, &class_node TSRMLS_CC); + + if (opline->op1_type == IS_CONST) { + zend_alloc_cache_slot(opline->op2.constant TSRMLS_CC); + } else { + zend_alloc_polymorphic_cache_slot(opline->op2.constant TSRMLS_CC); } +} +/* }}} */ - if (CG(current_namespace)) { - /* Prefix import name with current namespace name to avoid conflicts with classes */ - char *c_ns_name = emalloc(Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) + 1); - - zend_str_tolower_copy(c_ns_name, Z_STRVAL_P(CG(current_namespace)), Z_STRLEN_P(CG(current_namespace))); - c_ns_name[Z_STRLEN_P(CG(current_namespace))] = '\\'; - memcpy(c_ns_name+Z_STRLEN_P(CG(current_namespace))+1, lcname, Z_STRLEN_P(name)+1); - if (zend_hash_exists(CG(class_table), c_ns_name, Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name)+1)) { - char *tmp2 = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns)); - - if (Z_STRLEN_P(ns) != Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) || - memcmp(tmp2, c_ns_name, Z_STRLEN_P(ns))) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); +void zend_compile_resolve_class_name(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */ +{ + zend_ast *name_ast = ast->child[0]; + uint32_t fetch_type = zend_get_class_fetch_type(zend_ast_get_str(name_ast)); + + switch (fetch_type) { + case ZEND_FETCH_CLASS_SELF: + if (!CG(active_class_entry)) { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot access self::class when no class scope is active"); } - result->op_type = IS_CONST; - ZVAL_STR_COPY(&result->u.constant, CG(active_class_entry)->name); - efree(tmp2); - } - efree(c_ns_name); - } else if (zend_hash_find(CG(class_table), lcname, Z_STRLEN_P(name)+1, (void**)&pce) == SUCCESS && - (*pce)->type == ZEND_USER_CLASS && - (*pce)->info.user.filename == CG(compiled_filename)) { - char *c_tmp = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns)); ++ if (CG(active_class_entry)->ce_flags & ZEND_ACC_TRAIT) { ++ zval class_str_zv; ++ zend_ast *class_str_ast, *class_const_ast; + - if (Z_STRLEN_P(ns) != Z_STRLEN_P(name) || - memcmp(c_tmp, lcname, Z_STRLEN_P(ns))) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); - } - efree(c_tmp); - } ++ ZVAL_STRING(&class_str_zv, "class"); ++ class_str_ast = zend_ast_create_zval(&class_str_zv); ++ class_const_ast = zend_ast_create(ZEND_AST_CLASS_CONST, name_ast, class_str_ast); + - if (zend_hash_add(CG(current_import), lcname, Z_STRLEN_P(name)+1, &ns, sizeof(zval*), NULL) != SUCCESS) { - zend_error_noreturn(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); - } - if (warn) { - if (!strcmp(Z_STRVAL_P(name), "strict")) { - zend_error_noreturn(E_COMPILE_ERROR, "You seem to be trying to use a different language..."); - } - zend_error(E_WARNING, "The use statement with non-compound name '%s' has no effect", Z_STRVAL_P(name)); ++ zend_compile_expr(result, class_const_ast TSRMLS_CC); ++ ++ zval_ptr_dtor(&class_str_zv); ++ } else { ++ result->op_type = IS_CONST; ++ ZVAL_STR_COPY(&result->u.constant, CG(active_class_entry)->name); ++ } + break; + case ZEND_FETCH_CLASS_STATIC: + case ZEND_FETCH_CLASS_PARENT: + if (!CG(active_class_entry)) { + zend_error_noreturn(E_COMPILE_ERROR, + "Cannot access %s::class when no class scope is active", + fetch_type == ZEND_FETCH_CLASS_STATIC ? "static" : "parent"); + } else { + zval class_str_zv; + zend_ast *class_str_ast, *class_const_ast; + + ZVAL_STRING(&class_str_zv, "class"); + class_str_ast = zend_ast_create_zval(&class_str_zv); + class_const_ast = zend_ast_create( + ZEND_AST_CLASS_CONST, name_ast, class_str_ast); + + zend_compile_expr(result, class_const_ast TSRMLS_CC); + + zval_ptr_dtor(&class_str_zv); + } + break; + case ZEND_FETCH_CLASS_DEFAULT: + result->op_type = IS_CONST; + ZVAL_STR(&result->u.constant, zend_resolve_class_name_ast(name_ast TSRMLS_CC)); + break; + EMPTY_SWITCH_DEFAULT_CASE() } - efree(lcname); - zval_dtor(name); } /* }}} */