Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:31927 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 42820 invoked by uid 1010); 27 Aug 2007 06:15:10 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 42804 invoked from network); 27 Aug 2007 06:15:10 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 27 Aug 2007 06:15:10 -0000 Authentication-Results: pb1.pair.com smtp.mail=dmitry@zend.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=dmitry@zend.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain zend.com designates 212.25.124.162 as permitted sender) X-PHP-List-Original-Sender: dmitry@zend.com X-Host-Fingerprint: 212.25.124.162 mail.zend.com Linux 2.5 (sometimes 2.4) (4) Received: from [212.25.124.162] ([212.25.124.162:15854] helo=mail.zend.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id A8/B5-23538-CEB62D64 for ; Mon, 27 Aug 2007 02:15:10 -0400 Received: (qmail 17912 invoked from network); 27 Aug 2007 06:15:04 -0000 Received: from internal.zend.office (HELO thinkpad) (10.1.1.1) by internal.zend.office with SMTP; 27 Aug 2007 06:15:04 -0000 To: "'PHP Internals List'" Date: Mon, 27 Aug 2007 10:15:03 +0400 Message-ID: <000f01c7e871$9be827e0$6e02a8c0@thinkpad> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0010_01C7E893.22F9C7E0" X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook, Build 10.0.6626 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3138 Importance: Normal Subject: Namespaces and __autoload() From: dmitry@zend.com ("Dmitry Stogov") ------=_NextPart_000_0010_01C7E893.22F9C7E0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Hi, Please look into patch that implements __autoload() support for namespaces. The patch touches not only ZE but also SPL. In the following code we cannot exactly know if "Exception" class is from current namespace or it is an internal PHP class. num_args !=3D 1) {=0A= - zend_error(E_COMPILE_ERROR, "%s() must take exactly 1 argument", = ZEND_AUTOLOAD_FUNC_NAME);=0A= + CG(active_op_array)->num_args !=3D 1 && = CG(active_op_array)->num_args !=3D 2) {=0A= + zend_error(E_COMPILE_ERROR, "%s() must take exactly 1 or 2 = arguments", ZEND_AUTOLOAD_FUNC_NAME);=0A= }=0A= if (lcname.s !=3D lcname_buf) {=0A= efree(lcname.s);=0A= Index: Zend/zend_execute.h=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /repository/ZendEngine2/zend_execute.h,v=0A= retrieving revision 1.108=0A= diff -u -p -d -r1.108 zend_execute.h=0A= --- Zend/zend_execute.h 21 Jul 2007 00:34:41 -0000 1.108=0A= +++ Zend/zend_execute.h 24 Aug 2007 14:33:22 -0000=0A= @@ -75,6 +75,19 @@ static inline void safe_free_zval_ptr_re=0A= FREE_ZVAL_REL(p);=0A= }=0A= }=0A= +=0A= +/* The following constants should be used as "use_autoload" argument=0A= + for function zend_u_lookup_class_ex() and thay control the execution=0A= + of user function __autoload.=0A= + The function __autoload() is extended with additional boolean = argument=0A= + that shows if class is stricly required or may be absent.=0A= + This argument is necessary to avoid error reporting in user code = during=0A= + resolving of ambiguous class name in namespace.=0A= +*/=0A= +#define ZEND_AUTOLOAD_DISABLED 0 /* doesn't call __autoload() = */ =0A= +#define ZEND_AUTOLOAD_REQUIRED 1 /* calls __autoload($name, true); = */=0A= +#define ZEND_AUTOLOAD_ENABLED 2 /* calls __autoload($name, false); = */=0A= +=0A= ZEND_API int zend_lookup_class(char *name, int name_length, = zend_class_entry ***ce TSRMLS_DC);=0A= ZEND_API int zend_lookup_class_ex(char *name, int name_length, int = use_autoload, zend_class_entry ***ce TSRMLS_DC);=0A= ZEND_API int zend_u_lookup_class(zend_uchar type, zstr name, int = name_length, zend_class_entry ***ce TSRMLS_DC);=0A= Index: Zend/zend_execute_API.c=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /repository/ZendEngine2/zend_execute_API.c,v=0A= retrieving revision 1.413=0A= diff -u -p -d -r1.413 zend_execute_API.c=0A= --- Zend/zend_execute_API.c 24 Aug 2007 13:50:52 -0000 1.413=0A= +++ Zend/zend_execute_API.c 24 Aug 2007 14:33:22 -0000=0A= @@ -853,7 +853,7 @@ int zend_call_function(zend_fcall_info *=0A= } else if (calling_scope && clen =3D=3D sizeof("parent") - 1 && =0A= ZEND_U_EQUAL(Z_TYPE_P(fci->function_name), lcname, clen, = "parent", sizeof("parent")-1)) {=0A= ce_child =3D EG(active_op_array) && EG(active_op_array)->scope ? = EG(scope)->parent : NULL;=0A= - } else if (zend_u_lookup_class_ex(Z_TYPE_P(fci->function_name), = lcname, clen, 1, 0, &pce TSRMLS_CC) =3D=3D SUCCESS) {=0A= + } else if (zend_u_lookup_class_ex(Z_TYPE_P(fci->function_name), = lcname, clen, ZEND_AUTOLOAD_REQUIRED, 0, &pce TSRMLS_CC) =3D=3D SUCCESS) = {=0A= ce_child =3D *pce;=0A= }=0A= efree(lcname.v);=0A= @@ -1128,9 +1128,9 @@ int zend_call_function(zend_fcall_info *=0A= =0A= ZEND_API int zend_u_lookup_class_ex(zend_uchar type, zstr name, int = name_length, int use_autoload, int do_normalize, zend_class_entry ***ce = TSRMLS_DC) /* {{{ */=0A= {=0A= - zval **args[1];=0A= + zval **args[2];=0A= zval autoload_function;=0A= - zval *class_name_ptr;=0A= + zval *class_name_ptr, *required_ptr;=0A= zval *retval_ptr =3D NULL;=0A= int retval;=0A= unsigned int lc_name_len;=0A= @@ -1174,7 +1174,7 @@ ZEND_API int zend_u_lookup_class_ex(zend=0A= /* The compiler is not-reentrant. Make sure we __autoload() only = during run-time=0A= * (doesn't impact fuctionality of __autoload()=0A= */=0A= - if (!use_autoload || zend_is_compiling(TSRMLS_C)) {=0A= + if (use_autoload =3D=3D ZEND_AUTOLOAD_DISABLED || = zend_is_compiling(TSRMLS_C)) {=0A= if (do_normalize) {=0A= efree(lc_free.v);=0A= }=0A= @@ -1199,14 +1199,19 @@ ZEND_API int zend_u_lookup_class_ex(zend=0A= INIT_PZVAL(class_name_ptr);=0A= ZVAL_ZSTRL(class_name_ptr, type, name, name_length, 1);=0A= =0A= + ALLOC_ZVAL(required_ptr);=0A= + INIT_PZVAL(required_ptr);=0A= + ZVAL_BOOL(required_ptr, use_autoload =3D=3D ZEND_AUTOLOAD_REQUIRED);=0A= +=0A= args[0] =3D &class_name_ptr;=0A= + args[1] =3D &required_ptr;=0A= =0A= fcall_info.size =3D sizeof(fcall_info);=0A= fcall_info.function_table =3D EG(function_table);=0A= fcall_info.function_name =3D &autoload_function;=0A= fcall_info.symbol_table =3D NULL;=0A= fcall_info.retval_ptr_ptr =3D &retval_ptr;=0A= - fcall_info.param_count =3D 1;=0A= + fcall_info.param_count =3D 2;=0A= fcall_info.params =3D args;=0A= fcall_info.object_pp =3D NULL;=0A= fcall_info.no_separation =3D 1;=0A= @@ -1226,6 +1231,7 @@ ZEND_API int zend_u_lookup_class_ex(zend=0A= }=0A= =0A= zval_ptr_dtor(&class_name_ptr);=0A= + zval_ptr_dtor(&required_ptr);=0A= =0A= zend_u_hash_del(EG(in_autoload), type, lc_name, lc_name_len+1);=0A= =0A= @@ -1261,7 +1267,7 @@ ZEND_API int zend_u_lookup_class_ex(zend=0A= =0A= ZEND_API int zend_u_lookup_class(zend_uchar type, zstr name, int = name_length, zend_class_entry ***ce TSRMLS_DC) /* {{{ */=0A= {=0A= - return zend_u_lookup_class_ex(type, name, name_length, 1, 1, ce = TSRMLS_CC);=0A= + return zend_u_lookup_class_ex(type, name, name_length, = ZEND_AUTOLOAD_REQUIRED, 1, ce TSRMLS_CC);=0A= }=0A= /* }}} */=0A= =0A= @@ -1658,9 +1664,12 @@ void zend_unset_timeout(TSRMLS_D) /* {{{=0A= ZEND_API zend_class_entry *zend_u_fetch_class(zend_uchar type, zstr = class_name, uint class_name_len, int fetch_type TSRMLS_DC) /* {{{ */=0A= {=0A= zend_class_entry **pce;=0A= - int use_autoload =3D (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) ? 0 = : 1;=0A= int do_normalize =3D (fetch_type & ZEND_FETCH_CLASS_NO_NORMALIZE) ? 0 = : 1;=0A= int rt_ns_check =3D (fetch_type & ZEND_FETCH_CLASS_RT_NS_CHECK) ? 1 = : 0;=0A= + int use_autoload =3D (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) ? =0A= + ZEND_AUTOLOAD_DISABLED : =0A= + (rt_ns_check ? ZEND_AUTOLOAD_ENABLED :=0A= + ZEND_AUTOLOAD_REQUIRED);=0A= zstr lcname =3D class_name;=0A= =0A= fetch_type =3D fetch_type & ~ZEND_FETCH_CLASS_FLAGS;=0A= @@ -1705,7 +1714,7 @@ check_fetch_type:=0A= php_name.u =3D u_memrchr(lcname.u, ':', class_name_len);=0A= if (php_name.u) {=0A= php_name.u++;=0A= - if (zend_u_lookup_class_ex(type, php_name, = class_name_len-(php_name.u-lcname.u), 0, do_normalize, &pce = TSRMLS_CC)=3D=3DSUCCESS &&=0A= + if (zend_u_lookup_class_ex(type, php_name, = class_name_len-(php_name.u-lcname.u), ZEND_AUTOLOAD_DISABLED, = do_normalize, &pce TSRMLS_CC)=3D=3DSUCCESS &&=0A= (*pce)->type =3D=3D ZEND_INTERNAL_CLASS) {=0A= if (lcname.v !=3D class_name.v) {=0A= efree(lcname.v);=0A= @@ -1717,7 +1726,7 @@ check_fetch_type:=0A= php_name.s =3D zend_memrchr(lcname.s, ':', class_name_len);=0A= if (php_name.s) {=0A= php_name.s++;=0A= - if (zend_u_lookup_class_ex(type, php_name, = class_name_len-(php_name.s-lcname.s), 0, do_normalize, &pce = TSRMLS_CC)=3D=3DSUCCESS &&=0A= + if (zend_u_lookup_class_ex(type, php_name, = class_name_len-(php_name.s-lcname.s), ZEND_AUTOLOAD_DISABLED, = do_normalize, &pce TSRMLS_CC)=3D=3DSUCCESS &&=0A= (*pce)->type =3D=3D ZEND_INTERNAL_CLASS) {=0A= if (lcname.v !=3D class_name.v) {=0A= efree(lcname.v);=0A= @@ -1727,7 +1736,7 @@ check_fetch_type:=0A= }=0A= }=0A= }=0A= - if (use_autoload) {=0A= + if (use_autoload !=3D ZEND_AUTOLOAD_DISABLED) {=0A= if (fetch_type =3D=3D ZEND_FETCH_CLASS_INTERFACE) {=0A= zend_error(E_ERROR, "Interface '%R' not found", type, class_name);=0A= } else {=0A= Index: Zend/tests/errmsg_012.phpt=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /repository/ZendEngine2/tests/errmsg_012.phpt,v=0A= retrieving revision 1.1=0A= diff -u -p -d -r1.1 errmsg_012.phpt=0A= --- Zend/tests/errmsg_012.phpt 2 Feb 2007 12:53:54 -0000 1.1=0A= +++ Zend/tests/errmsg_012.phpt 24 Aug 2007 14:33:22 -0000=0A= @@ -1,11 +1,11 @@=0A= --TEST--=0A= -errmsg: __autoload() must take exactly 1 argument=0A= +errmsg: __autoload() must take exactly 1 or 2 arguments=0A= --FILE--=0A= =0A= --EXPECTF-- =0A= -Fatal error: __autoload() must take exactly 1 argument in %s on line %d=0A= +Fatal error: __autoload() must take exactly 1 or 2 arguments in %s on = line %d=0A= Index: Zend/tests/ns_054.phpt=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: Zend/tests/ns_054.phpt=0A= diff -N Zend/tests/ns_054.phpt=0A= --- /dev/null 1 Jan 1970 00:00:00 -0000=0A= +++ Zend/tests/ns_054.phpt 24 Aug 2007 14:33:22 -0000=0A= @@ -0,0 +1,17 @@=0A= +--TEST--=0A= +054: namespaces and __autoload()=0A= +--FILE--=0A= +=0A= +--FILE--=0A= +obj ? &alfi->obj : NULL, alfi->ce, = &alfi->func_ptr, func_name_type, func_name, func_name_len, &retval, 1, = zclass_name, NULL TSRMLS_CC);=0A= + zend_u_call_method(alfi->obj ? &alfi->obj : NULL, alfi->ce, = &alfi->func_ptr, func_name_type, func_name, func_name_len, &retval, 2, = zclass_name, zrequired TSRMLS_CC);=0A= if (retval) {=0A= zval_ptr_dtor(&retval); =0A= }=0A= @@ -387,6 +408,7 @@ PHP_FUNCTION(spl_autoload_call)=0A= zend_call_method_with_1_params(NULL, NULL, NULL, "spl_autoload", = NULL, zclass_name);=0A= }=0A= zval_ptr_dtor(&zclass_name);=0A= + zval_ptr_dtor(&zrequired);=0A= } /* }}} */=0A= =0A= /* {{{ proto bool spl_autoload_register([mixed autoload_function =3D = "spl_autoload" [, throw =3D true]]) U=0A= ------=_NextPart_000_0010_01C7E893.22F9C7E0--