]> granicus.if.org Git - php/commitdiff
Changed "instanceof" and "catch" operators, is_a() and is_subclass_of() functions...
authorDmitry Stogov <dmitry@php.net>
Fri, 9 Sep 2005 06:48:49 +0000 (06:48 +0000)
committerDmitry Stogov <dmitry@php.net>
Fri, 9 Sep 2005 06:48:49 +0000 (06:48 +0000)
NEWS
Zend/tests/catch.phpt [new file with mode: 0755]
Zend/tests/instanceof.phpt [new file with mode: 0755]
Zend/tests/is_a.phpt [new file with mode: 0755]
Zend/zend_builtin_functions.c
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.h
Zend/zend_execute_API.c

diff --git a/NEWS b/NEWS
index 7ba55c4c7fd0461a4c7f5c29f932f6f5ad0f3d8e..ee93fc89c5afefae68cd9d5f95848e4f6d6e0d3b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,8 @@
 PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? Aug 2005, PHP 5.1 Release Candidate 2
+- Changed "instanceof" and "catch" operators, is_a() and is_subclass_of()
+  functions to not call __autoload(). (Dmitry)
 - Added support for class constants and static members for internal
   classes. (Dmitry, Michael Wallner)
 - Added "new_link" parameter to mssql_connect(). Bug #34369. (Frank)
diff --git a/Zend/tests/catch.phpt b/Zend/tests/catch.phpt
new file mode 100755 (executable)
index 0000000..0ec5cf7
--- /dev/null
@@ -0,0 +1,23 @@
+--TEST--
+catch shouldn't call __autoload
+--FILE--
+<?php
+function __autoload($name) {
+       echo("AUTOLOAD '$name'\n");
+       eval("class $name {}");
+}
+
+
+try {
+} catch (A $e) {
+}
+
+try {
+  throw new Exception();
+} catch (B $e) {
+} catch (Exception $e) {
+       echo "ok\n";
+}
+?>
+--EXPECT--
+ok
diff --git a/Zend/tests/instanceof.phpt b/Zend/tests/instanceof.phpt
new file mode 100755 (executable)
index 0000000..8bcbede
--- /dev/null
@@ -0,0 +1,18 @@
+--TEST--
+instanceof shouldn't call __autoload
+--FILE--
+<?php
+function __autoload($name) {
+       echo("AUTOLOAD '$name'\n");
+       eval("class $name {}");
+}
+
+class A {
+}
+$a = new A;
+var_dump($a instanceof B);
+var_dump($a instanceof A);
+?>
+--EXPECT--
+bool(false)
+bool(true)
diff --git a/Zend/tests/is_a.phpt b/Zend/tests/is_a.phpt
new file mode 100755 (executable)
index 0000000..dfc0d59
--- /dev/null
@@ -0,0 +1,51 @@
+--TEST--
+is_a() and is_subclass_of() shouldn't call __autoload
+--INI--
+error_reporting=4095
+--FILE--
+<?php
+function __autoload($name) {
+       echo("AUTOLOAD '$name'\n");
+       eval("class $name {}");
+}
+
+class BASE {
+}
+
+interface INT {
+}
+
+class A extends BASE implements INT {
+}
+
+$a = new A;
+var_dump(is_a($a, "B1"));
+var_dump(is_a($a, "A"));
+var_dump(is_a($a, "BASE"));
+var_dump(is_a($a, "INT"));
+var_dump(is_subclass_of($a, "B2"));
+var_dump(is_subclass_of($a, "A"));
+var_dump(is_subclass_of($a, "BASE"));
+var_dump(is_subclass_of($a, "INT"));
+
+var_dump(is_subclass_of("X1", "X2"));
+?>
+--EXPECTF--
+Strict Standards: is_a(): Deprecated. Please use the instanceof operator in %sis_a.php on line 17
+bool(false)
+
+Strict Standards: is_a(): Deprecated. Please use the instanceof operator in %sis_a.php on line 18
+bool(true)
+
+Strict Standards: is_a(): Deprecated. Please use the instanceof operator in %sis_a.php on line 19
+bool(true)
+
+Strict Standards: is_a(): Deprecated. Please use the instanceof operator in %sis_a.php on line 20
+bool(true)
+bool(false)
+bool(false)
+bool(true)
+bool(false)
+AUTOLOAD 'X1'
+AUTOLOAD 'X2'
+bool(false)
index e46a9ef0a978530528e55402f1629baf3ebfc3a3..ccadc146de55a09afe1b5097f8d03b55e0e2328c 100644 (file)
@@ -625,7 +625,7 @@ static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass)
 
        convert_to_string_ex(class_name);
 
-       if (zend_lookup_class(Z_STRVAL_PP(class_name), Z_STRLEN_PP(class_name), &ce TSRMLS_CC) == FAILURE) {
+       if (zend_lookup_class_ex(Z_STRVAL_PP(class_name), Z_STRLEN_PP(class_name), (instance_ce != NULL), &ce TSRMLS_CC) == FAILURE) {
                retval = 0;
        } else {
                if (only_subclass) {
index c1a4f586dd00e6adf89c6f8a8d64ae8d5a8724a8..1cfcef50875daefbcb622810827f603cdec57335 100644 (file)
@@ -1712,6 +1712,13 @@ void zend_do_begin_catch(znode *try_token, znode *catch_class, znode *catch_var,
        long catch_op_number = get_next_op_number(CG(active_op_array));
        zend_op *opline;
        
+       if (catch_op_number > 0) {
+               opline = &CG(active_op_array)->opcodes[catch_op_number-1];
+               if (opline->opcode == ZEND_FETCH_CLASS) {
+                       opline->extended_value |= ZEND_FETCH_CLASS_NO_AUTOLOAD;
+               }
+       }
+
        opline = get_next_op(CG(active_op_array) TSRMLS_CC);
        opline->opcode = ZEND_CATCH;
        opline->op1 = *catch_class;
@@ -3468,8 +3475,17 @@ void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC
 
 void zend_do_instanceof(znode *result, znode *expr, znode *class_znode, int type TSRMLS_DC)
 {
-       zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
+       int last_op_number = get_next_op_number(CG(active_op_array));
+       zend_op *opline;
 
+       if (last_op_number > 0) {
+               opline = &CG(active_op_array)->opcodes[last_op_number-1];
+               if (opline->opcode == ZEND_FETCH_CLASS) {
+                       opline->extended_value |= ZEND_FETCH_CLASS_NO_AUTOLOAD;
+               }
+       }
+
+       opline = get_next_op(CG(active_op_array) TSRMLS_CC);
        opline->opcode = ZEND_INSTANCEOF;
        opline->result.op_type = IS_TMP_VAR;
        opline->result.u.var = get_temporary_variable(CG(active_op_array));
index b63dd8c90a308499454f6f4d6564dac1415291bb..006f0eedd8b8c036b7d4e857d546849764feb0c6 100644 (file)
@@ -583,7 +583,7 @@ int zendlex(znode *zendlval TSRMLS_DC);
 #define ZEND_FETCH_CLASS_GLOBAL                4
 #define ZEND_FETCH_CLASS_AUTO          5
 #define ZEND_FETCH_CLASS_INTERFACE     6
-
+#define ZEND_FETCH_CLASS_NO_AUTOLOAD 0x80
 
 /* variable parsing type (compile-time) */
 #define ZEND_PARSED_MEMBER                             (1<<0)
index bf7657ed0f5ab5c2e20844a2d85971f12fced8ae..98a6b0494911063c7f584ef37908d8e43d82bf5f 100644 (file)
@@ -65,6 +65,7 @@ static inline void safe_free_zval_ptr_rel(zval *p ZEND_FILE_LINE_DC ZEND_FILE_LI
        }
 }
 ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***ce TSRMLS_DC);
+ZEND_API int zend_lookup_class_ex(char *name, int name_length, int use_autoload, zend_class_entry ***ce TSRMLS_DC);
 ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC);
 ZEND_API int zend_eval_string_ex(char *str, zval *retval_ptr, char *string_name, int handle_exceptions TSRMLS_DC);
 
index dcc1249f80754bca96072fa5d5f8ce42765c4559..9022ee0de34eb05cb0d108d3046844fd5816f770 100644 (file)
@@ -908,7 +908,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
 }
 
 
-ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***ce TSRMLS_DC)
+ZEND_API int zend_lookup_class_ex(char *name, int name_length, int use_autoload, zend_class_entry ***ce TSRMLS_DC)
 {
        zval **args[1];
        zval autoload_function;
@@ -936,7 +936,7 @@ ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***
        /* The compiler is not-reentrant. Make sure we __autoload() only during run-time
         * (doesn't impact fuctionality of __autoload()
        */
-       if (zend_is_compiling(TSRMLS_C)) {
+       if (!use_autoload || zend_is_compiling(TSRMLS_C)) {
                free_alloca(lc_name);
                return FAILURE;
        }
@@ -1004,6 +1004,11 @@ ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***
        return retval;
 }
 
+ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***ce TSRMLS_DC)
+{
+       return zend_lookup_class_ex(name, name_length, 1, ce TSRMLS_CC);
+}
+
 ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
 {
        zval pv;
@@ -1329,7 +1334,9 @@ void zend_unset_timeout(TSRMLS_D)
 zend_class_entry *zend_fetch_class(char *class_name, uint class_name_len, int fetch_type TSRMLS_DC)
 {
        zend_class_entry **pce;
+       int use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) == 0;
 
+       fetch_type = fetch_type & ~ZEND_FETCH_CLASS_NO_AUTOLOAD;
 check_fetch_type:
        switch (fetch_type) {
                case ZEND_FETCH_CLASS_SELF:
@@ -1354,12 +1361,15 @@ check_fetch_type:
                        break;
        }
 
-       if (zend_lookup_class(class_name, class_name_len, &pce TSRMLS_CC)==FAILURE) {
-               if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) {
-                       zend_error(E_ERROR, "Interface '%s' not found", class_name);
-               } else {
-                       zend_error(E_ERROR, "Class '%s' not found", class_name);
+       if (zend_lookup_class_ex(class_name, class_name_len, use_autoload, &pce TSRMLS_CC)==FAILURE) {
+               if (use_autoload) {
+                       if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) {
+                               zend_error(E_ERROR, "Interface '%s' not found", class_name);
+                       } else {
+                               zend_error(E_ERROR, "Class '%s' not found", class_name);
+                       }
                }
+               return NULL;
        }
        return *pce;
 }