Hi,

I have separated fixes and optimizations from the delayed early binding itself 
and added comments about options. Now the patch must be more clear.

The order of actual class declaration in PHP scripts doesn't follow to syntax 
order. Some classes might be declared at compile-time (early binding - the 
classes which don't implement interfaces and doesn't have parent or have parent 
class that is known during compilation) others only in run-time. Many 
applications depend on this order and will be broken in case if we disable 
early binding. On the other hand early binding provides a big problem for 
opcode caches which are not able to emulate it properly. The early binding 
itself is impossible because caches cannot create cross-script dependencies or 
dependencies from internal classes. So most of them try to emulate early 
binding during restoring script from cache, but in fact they may declare 
classes that were never declared at compile time (for example class 
declarations wrapped by тАЬifтАЭ statementтАЭ).

The path for PHP_5_3 is going to provide a general solution to control some 
aspect of PHP compilation. The patch introduces CG(compiler_options) that is a 
bit-set of compiler flags. ZE provides two default sets of the options. One for 
script compilation and another for code evaluation. Some extensions like opcode 
caches and debuggers might set (or reset) individual flags in the 
CG(compiler_options).

The patch defines the following options:

ZEND_COMPILE_EXTENDED_INFO is a replacement of CG(extended_info)

ZEND_COMPILE_HANDLE_OP_ARRAY is a replacement  CG(handle_op_arrays)

ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS disables generation of direct calls to 
internal functions (ZEND_DO_FCALL) and use indirect calls 
(ZEND_INIT_FCALL_BY_NAME + ZEND_DO_FCALL_BY_NAME). This flag may be useful if 
script compiled by one PHP binary but executed by another, which may miss some 
internal functions.

ZEND_COMPILE_IGNORE_INTERNAL_CLASSES disables usage of internal classes during 
compilation. It disables early binding of classes with parent internal classes. 
Also all non-compound names in namespaces might be resolved to internal classes 
at runtime.

ZEND_COMPILE_DELAYED_BINDING changes ZEND_DECLARE_INHERITED_CLASS opcode into 
ZEND_DECLARE_INHERITED_CLASS_DELAYD for all opcodes that were failed to perform 
early binding because of inexistence of parent class. This flag is especial 
useful with caches which have to perform early binding during 
script-loading-time instead of compile-time. In case if parent class doesn't 
exists at script-loading-time too, actual class declaration will be finally 
delayed to run-time.

So to use delayed early binding, opcode cache should set proper flags and then 
call the original compiler.

cache_compile_file() {
        ...
        orig_compiler_options = CG(compiler_options);
        CG(compiler_options) |= ZEND_COMPILE_IGNORE_INTERNAL_CLASSES |
                ZEND_COMPILE_DELAYED_BINDING;
        ret = orig_compile_file();
        CG(compiler_options) = orig_compiler_options;
        ...
        retur ret;
}

And then call to zend_do_delayed_early_binding() for op_array of each restored 
script.

Thanks. Dmitry.
Index: Zend/zend.c
===================================================================
RCS file: /repository/ZendEngine2/zend.c,v
retrieving revision 1.308.2.12.2.35.2.10
diff -u -p -d -r1.308.2.12.2.35.2.10 zend.c
--- Zend/zend.c 8 Mar 2008 21:54:03 -0000       1.308.2.12.2.35.2.10
+++ Zend/zend.c 12 Mar 2008 11:06:36 -0000
@@ -446,15 +446,15 @@ static void register_standard_class(TSRM
 /* }}} */
 
 #ifdef ZTS
-static zend_bool asp_tags_default              = 0;
-static zend_bool short_tags_default            = 1;
-static zend_bool ct_pass_ref_default   = 1;
-static zend_bool extended_info_default = 0;
+static zend_bool asp_tags_default                = 0;
+static zend_bool short_tags_default              = 1;
+static zend_bool ct_pass_ref_default     = 1;
+static zend_uint compiler_options_default = ZEND_COMPILE_DEFAULT;
 #else
-# define asp_tags_default              0
-# define short_tags_default            1
-# define ct_pass_ref_default   1
-# define extended_info_default 0
+# define asp_tags_default                      0
+# define short_tags_default                    1
+# define ct_pass_ref_default           1
+# define compiler_options_default      ZEND_COMPILE_DEFAULT
 #endif
 
 static void zend_set_default_compile_time_values(TSRMLS_D) /* {{{ */
@@ -463,7 +463,7 @@ static void zend_set_default_compile_tim
        CG(asp_tags) = asp_tags_default;
        CG(short_tags) = short_tags_default;
        CG(allow_call_time_pass_reference) = ct_pass_ref_default;
-       CG(extended_info) = extended_info_default;
+       CG(compiler_options) = compiler_options_default;
 }
 /* }}} */
 
@@ -728,7 +728,7 @@ void zend_post_startup(TSRMLS_D) /* {{{ 
        asp_tags_default = CG(asp_tags);
        short_tags_default = CG(short_tags);
        ct_pass_ref_default = CG(allow_call_time_pass_reference);
-       extended_info_default = CG(extended_info);
+       compiler_options_default = CG(compiler_options);
 
        zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
        free(compiler_globals->function_table);
Index: Zend/zend_compile.c
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.c,v
retrieving revision 1.647.2.27.2.41.2.49
diff -u -p -d -r1.647.2.27.2.41.2.49 zend_compile.c
--- Zend/zend_compile.c 12 Mar 2008 10:40:02 -0000      1.647.2.27.2.41.2.49
+++ Zend/zend_compile.c 12 Mar 2008 11:06:37 -0000
@@ -137,7 +137,6 @@ void zend_init_compiler_data_structures(
        zend_llist_init(&CG(list_llist), sizeof(list_llist_element), NULL, 0);
        zend_llist_init(&CG(dimension_llist), sizeof(int), NULL, 0);
        zend_stack_init(&CG(list_stack));
-       CG(handle_op_arrays) = 1;
        CG(in_compilation) = 0;
        CG(start_lineno) = 0;
        CG(current_namespace) = NULL;
@@ -1259,7 +1258,7 @@ void zend_do_begin_function_declaration(
                zend_hash_update(CG(function_table), 
opline->op1.u.constant.value.str.val, opline->op1.u.constant.value.str.len, 
&op_array, sizeof(zend_op_array), (void **) &CG(active_op_array));
        }
 
-       if (CG(extended_info)) {
+       if (CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) {
                zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 
                opline->opcode = ZEND_EXT_NOP;
@@ -1438,7 +1437,9 @@ int zend_do_begin_function_call(znode *f
        }
        
        lcname = zend_str_tolower_dup(function_name->u.constant.value.str.val, 
function_name->u.constant.value.str.len);
-       if (zend_hash_find(CG(function_table), lcname, 
function_name->u.constant.value.str.len+1, (void **) &function)==FAILURE) {
+       if ((zend_hash_find(CG(function_table), lcname, 
function_name->u.constant.value.str.len+1, (void **) &function)==FAILURE) ||
+               ((CG(compiler_options) & 
ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS) &&
+                (function->type == ZEND_INTERNAL_FUNCTION))) {
                zend_do_begin_dynamic_function_call(function_name, prefix_len 
TSRMLS_CC);
                efree(lcname);
                return 1; /* Dynamic */
@@ -1621,8 +1622,9 @@ void zend_resolve_class_name(znode *clas
                                efree(ns_lcname);
                        }
 
-                       if (zend_hash_find(CG(class_table), lcname, 
Z_STRLEN(class_name->u.constant)+1, (void**)&pce) == SUCCESS &&
-                           (*pce)->type == ZEND_INTERNAL_CLASS) {
+                       if ((CG(compiler_options) & 
ZEND_COMPILE_IGNORE_INTERNAL_CLASSES) ||
+                           (zend_hash_find(CG(class_table), lcname, 
Z_STRLEN(class_name->u.constant)+1, (void**)&pce) == SUCCESS &&
+                           (*pce)->type == ZEND_INTERNAL_CLASS)) {
                            /* There is an internal class with the same name 
exists.
                               PHP will need to perform additional cheks at 
run-time to
                               determine if we assume class in current 
namespace or
@@ -2744,7 +2746,6 @@ void zend_do_early_binding(TSRMLS_D)
 {
        zend_op *opline = 
&CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
        HashTable *table;
-       zend_bool is_abstract_class = 0;
 
        while (opline->opcode == ZEND_TICKS && opline > 
CG(active_op_array)->opcodes) {
                opline--;
@@ -2758,57 +2759,49 @@ void zend_do_early_binding(TSRMLS_D)
                        table = CG(function_table);
                        break;
                case ZEND_DECLARE_CLASS:
+                       if (do_bind_class(opline, CG(class_table), 1 TSRMLS_CC) 
== NULL) {
+                               return;
+                       }
+                       table = CG(class_table);
+                       break;
                case ZEND_DECLARE_INHERITED_CLASS:
-                       is_abstract_class = 1;
-                       /* break missing intentionally */
-               case ZEND_VERIFY_ABSTRACT_CLASS: {
-                               zend_op *verify_abstract_class_op = opline;
-
-                               if (!is_abstract_class) {
-                                       opline--;
-                               }
-                               if (opline->opcode == ZEND_DECLARE_CLASS) {
-                                       if (do_bind_class(opline, 
CG(class_table), 1 TSRMLS_CC) == NULL) {
-                                               return;
-                                       }
-                               } else if (opline->opcode == 
ZEND_DECLARE_INHERITED_CLASS) {
-                                       zval *parent_name = 
&(opline-1)->op2.u.constant;
-                                       zend_class_entry **pce;
+                       {
+                               zend_op *fetch_class_opline = opline-1;
+                               zval *parent_name = 
&fetch_class_opline->op2.u.constant;
+                               zend_class_entry **pce;
 
-                                       if 
(zend_lookup_class(Z_STRVAL_P(parent_name), Z_STRLEN_P(parent_name), &pce 
TSRMLS_CC) == FAILURE) {
-                                               return;
-                                       }
-                                       if (do_bind_inherited_class(opline, 
CG(class_table), *pce, 1 TSRMLS_CC) == NULL) {
-                                               return;
-                                       }
-                                       /* clear unnecessary ZEND_FETCH_CLASS 
opcode */
-                                       if (opline > 
CG(active_op_array)->opcodes &&
-                                           (opline-1)->opcode == 
ZEND_FETCH_CLASS) {
-                                         zend_op *fetch_class_opline = 
opline-1;
+                               if ((zend_lookup_class(Z_STRVAL_P(parent_name), 
Z_STRLEN_P(parent_name), &pce TSRMLS_CC) == FAILURE) ||
+                                   ((CG(compiler_options) & 
ZEND_COMPILE_IGNORE_INTERNAL_CLASSES) &&
+                                    ((*pce)->type == ZEND_INTERNAL_CLASS))) {
+                                   if (CG(compiler_options) & 
ZEND_COMPILE_DELAYED_BINDING) {
+                                               zend_uint *opline_num = 
&CG(active_op_array)->early_binding;
 
-                                               
zval_dtor(&fetch_class_opline->op2.u.constant);
-                                               fetch_class_opline->opcode = 
ZEND_NOP;
-                                               
memset(&fetch_class_opline->op1, 0, sizeof(znode));
-                                               
memset(&fetch_class_opline->op2, 0, sizeof(znode));
-                                               
SET_UNUSED(fetch_class_opline->op1);
-                                               
SET_UNUSED(fetch_class_opline->op2);
-                                               
SET_UNUSED(fetch_class_opline->result);
+                                               while (*opline_num != -1) {
+                                                       opline_num = 
&CG(active_op_array)->opcodes[*opline_num].result.u.opline_num;
+                                               }
+                                               *opline_num = opline - 
CG(active_op_array)->opcodes;
+                                               opline->opcode = 
ZEND_DECLARE_INHERITED_CLASS_DELAYED;
+                                               opline->result.op_type = 
IS_UNUSED;
+                                               opline->result.u.opline_num = 
-1;
                                        }
-                               } else {
-                                       /* We currently don't early-bind 
classes that implement interfaces */
                                        return;
                                }
-                               table = CG(class_table);
-                               if (!is_abstract_class) {
-                                       /* clear the verify_abstract_class op */
-                                       init_op(verify_abstract_class_op 
TSRMLS_CC);
-                                       
SET_UNUSED(verify_abstract_class_op->op1);
-                                       
SET_UNUSED(verify_abstract_class_op->op2);
-                                       verify_abstract_class_op->opcode = 
ZEND_NOP;
+                               if (do_bind_inherited_class(opline, 
CG(class_table), *pce, 1 TSRMLS_CC) == NULL) {
+                                       return;
                                }
-                       }
+                               /* clear unnecessary ZEND_FETCH_CLASS opcode */
+                               zval_dtor(&fetch_class_opline->op2.u.constant);
+                               fetch_class_opline->opcode = ZEND_NOP;
+                               memset(&fetch_class_opline->op1, 0, 
sizeof(znode));
+                               memset(&fetch_class_opline->op2, 0, 
sizeof(znode));
+                               SET_UNUSED(fetch_class_opline->op1);
+                               SET_UNUSED(fetch_class_opline->op2);
+                               SET_UNUSED(fetch_class_opline->result);
 
-                       break;
+                               table = CG(class_table);
+                               break;
+                       }
+               case ZEND_VERIFY_ABSTRACT_CLASS:
                case ZEND_ADD_INTERFACE:
                        /* We currently don't early-bind classes that implement 
interfaces */
                        return;
@@ -2827,6 +2820,23 @@ void zend_do_early_binding(TSRMLS_D)
        SET_UNUSED(opline->op2);
 }
 
+ZEND_API void zend_do_delayed_early_binding(zend_op_array *op_array TSRMLS_DC)
+{
+       if (op_array->early_binding != -1) {
+               zend_bool orig_in_compilation = CG(in_compilation);
+               zend_uint opline_num = op_array->early_binding;
+               zend_class_entry **pce;
+
+               CG(in_compilation) = 1;
+               while (opline_num != -1) {
+                       if 
(zend_lookup_class(Z_STRVAL(op_array->opcodes[opline_num-1].op2.u.constant), 
Z_STRLEN(op_array->opcodes[opline_num-1].op2.u.constant), &pce TSRMLS_CC) == 
SUCCESS) {
+                               
do_bind_inherited_class(&op_array->opcodes[opline_num], EG(class_table), *pce, 
1 TSRMLS_CC);
+                       }
+                       opline_num = 
op_array->opcodes[opline_num].result.u.opline_num;
+               }
+               CG(in_compilation) = orig_in_compilation;
+       }
+}
 
 void zend_do_boolean_or_begin(znode *expr1, znode *op_token TSRMLS_DC)
 {
@@ -4500,7 +4510,7 @@ void zend_do_extended_info(TSRMLS_D)
 {
        zend_op *opline;
 
-       if (!CG(extended_info)) {
+       if (!(CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)) {
                return;
        }
 
@@ -4516,7 +4526,7 @@ void zend_do_extended_fcall_begin(TSRMLS
 {
        zend_op *opline;
 
-       if (!CG(extended_info)) {
+       if (!(CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)) {
                return;
        }
 
@@ -4532,7 +4542,7 @@ void zend_do_extended_fcall_end(TSRMLS_D
 {
        zend_op *opline;
 
-       if (!CG(extended_info)) {
+       if (!(CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO)) {
                return;
        }
 
Index: Zend/zend_compile.h
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.h,v
retrieving revision 1.316.2.8.2.12.2.15
diff -u -p -d -r1.316.2.8.2.12.2.15 zend_compile.h
--- Zend/zend_compile.h 12 Mar 2008 09:46:42 -0000      1.316.2.8.2.12.2.15
+++ Zend/zend_compile.h 12 Mar 2008 11:06:37 -0000
@@ -224,6 +224,7 @@ struct _zend_op_array {
        zend_uint line_end;
        char *doc_comment;
        zend_uint doc_comment_len;
+       zend_uint early_binding; /* the linked list of delayed declarations */
 
        void *reserved[ZEND_MAX_RESERVED_RESOURCES];
 };
@@ -428,6 +429,7 @@ void zend_do_implements_interface(znode 
 
 ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry 
*parent_ce TSRMLS_DC);
 void zend_do_early_binding(TSRMLS_D);
+ZEND_API void zend_do_delayed_early_binding(zend_op_array *op_array TSRMLS_DC);
 
 void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC);
 
@@ -720,6 +722,32 @@ END_EXTERN_C()
 #define ZEND_TOSTRING_FUNC_NAME     "__tostring"
 #define ZEND_AUTOLOAD_FUNC_NAME     "__autoload"
 
+/* The following constants may be combined in CG(compiler_options)
+ * to change the default compiler behavior */
+
+/* generate extended debug information */
+#define ZEND_COMPILE_EXTENDED_INFO                             (1<<0)
+
+/* call op_array handler of extendions */
+#define ZEND_COMPILE_HANDLE_OP_ARRAY            (1<<1)
+
+/* generate ZEND_DO_FCALL_BY_NAME for internal functions instead of 
ZEND_DO_FCALL */
+#define ZEND_COMPILE_IGNORE_INTERNAL_FUNCTIONS (1<<2)
+
+/* don't perform early binding for classes inherited form internal ones;
+ * in namespaces assume that internal class that doesn't exist at compile-time
+ * may apper in run-time */
+#define ZEND_COMPILE_IGNORE_INTERNAL_CLASSES   (1<<3)
+
+/* generate ZEND_DECLARE_INHERITED_CLASS_DELAYED opcode to delay early binding 
*/
+#define ZEND_COMPILE_DELAYED_BINDING                   (1<<4)
+
+/* The default value for CG(compiler_options) */
+#define ZEND_COMPILE_DEFAULT                                   
ZEND_COMPILE_HANDLE_OP_ARRAY
+
+/* The default value for CG(compiler_options) during eval() */
+#define ZEND_COMPILE_DEFAULT_FOR_EVAL                  0
+
 #endif /* ZEND_COMPILE_H */
 
 /*
Index: Zend/zend_execute_API.c
===================================================================
RCS file: /repository/ZendEngine2/zend_execute_API.c,v
retrieving revision 1.331.2.20.2.24.2.28
diff -u -p -d -r1.331.2.20.2.24.2.28 zend_execute_API.c
--- Zend/zend_execute_API.c     9 Mar 2008 20:52:29 -0000       
1.331.2.20.2.24.2.28
+++ Zend/zend_execute_API.c     12 Mar 2008 11:06:37 -0000
@@ -1264,7 +1264,7 @@ ZEND_API int zend_eval_string(char *str,
        zval pv;
        zend_op_array *new_op_array;
        zend_op_array *original_active_op_array = EG(active_op_array);
-       zend_uchar original_handle_op_arrays;
+       zend_uint original_compiler_options;
        int retval;
 
        if (retval_ptr) {
@@ -1284,10 +1284,10 @@ ZEND_API int zend_eval_string(char *str,
 
        /*printf("Evaluating '%s'\n", pv.value.str.val);*/
 
-       original_handle_op_arrays = CG(handle_op_arrays);
-       CG(handle_op_arrays) = 0;
+       original_compiler_options = CG(compiler_options);
+       CG(handle_op_arrays) = ZEND_COMPILE_DEFAULT_FOR_EVAL;
        new_op_array = zend_compile_string(&pv, string_name TSRMLS_CC);
-       CG(handle_op_arrays) = original_handle_op_arrays;
+       CG(compiler_options) = original_compiler_options;
 
        if (new_op_array) {
                zval *local_retval_ptr=NULL;
Index: Zend/zend_globals.h
===================================================================
RCS file: /repository/ZendEngine2/zend_globals.h,v
retrieving revision 1.141.2.3.2.7.2.8
diff -u -p -d -r1.141.2.3.2.7.2.8 zend_globals.h
--- Zend/zend_globals.h 8 Mar 2008 21:54:03 -0000       1.141.2.3.2.7.2.8
+++ Zend/zend_globals.h 12 Mar 2008 11:06:37 -0000
@@ -59,6 +59,9 @@ END_EXTERN_C()
 /* excpt.h on Digital Unix 4.0 defines function_table */
 #undef function_table
 
+#define ZEND_EARLY_BINDING_COMPILE_TIME 0
+#define ZEND_EARLY_BINDING_DELAYED      1
+#define ZEND_EARLY_BINDING_DELAYED_ALL  2
 
 typedef struct _zend_declarables {
        zval ticks;
@@ -106,7 +109,6 @@ struct _zend_compiler_globals {
        zend_declarables declarables;
 
        /* For extensions support */
-       zend_bool extended_info;        /* generate extension information for 
debugger/profiler */
        zend_bool handle_op_arrays;     /* run op_arrays through op_array 
handlers */
 
        zend_bool unclean_shutdown;
@@ -131,6 +133,8 @@ struct _zend_compiler_globals {
        char *doc_comment;
        zend_uint doc_comment_len;
 
+       zend_uint compiler_options; /* set of ZEND_COMPILE_* constants */
+
        zval      *current_namespace;
        HashTable *current_import;
 
Index: Zend/zend_opcode.c
===================================================================
RCS file: /repository/ZendEngine2/zend_opcode.c,v
retrieving revision 1.110.2.6.2.3.2.5
diff -u -p -d -r1.110.2.6.2.3.2.5 zend_opcode.c
--- Zend/zend_opcode.c  31 Dec 2007 07:17:04 -0000      1.110.2.6.2.3.2.5
+++ Zend/zend_opcode.c  12 Mar 2008 11:06:37 -0000
@@ -101,6 +101,8 @@ void init_op_array(zend_op_array *op_arr
 
        op_array->fn_flags = CG(interactive)?ZEND_ACC_INTERACTIVE:0;
 
+       op_array->early_binding = -1;
+
        memset(op_array->reserved, 0, ZEND_MAX_RESERVED_RESOURCES * 
sizeof(void*));
 
        zend_llist_apply_with_argument(&zend_extensions, 
(llist_apply_with_arg_func_t) zend_extension_op_array_ctor_handler, op_array 
TSRMLS_CC);
@@ -364,10 +366,10 @@ int pass_two(zend_op_array *op_array TSR
        if (op_array->type!=ZEND_USER_FUNCTION && 
op_array->type!=ZEND_EVAL_CODE) {
                return 0;
        }
-       if (CG(extended_info)) {
+       if (CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) {
                zend_update_extended_info(op_array TSRMLS_CC);
        }
-       if (CG(handle_op_arrays)) {
+       if (CG(compiler_options) & ZEND_COMPILE_HANDLE_OP_ARRAY) {
                zend_llist_apply_with_argument(&zend_extensions, 
(llist_apply_with_arg_func_t) zend_extension_op_array_handler, op_array 
TSRMLS_CC);
        }
 
Index: Zend/zend_vm_def.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_def.h,v
retrieving revision 1.59.2.29.2.48.2.42
diff -u -p -d -r1.59.2.29.2.48.2.42 zend_vm_def.h
--- Zend/zend_vm_def.h  12 Mar 2008 10:32:11 -0000      1.59.2.29.2.48.2.42
+++ Zend/zend_vm_def.h  12 Mar 2008 11:06:37 -0000
@@ -3962,6 +3962,19 @@ ZEND_VM_HANDLER(140, ZEND_DECLARE_INHERI
        ZEND_VM_NEXT_OPCODE();
 }
 
+ZEND_VM_HANDLER(145, ZEND_DECLARE_INHERITED_CLASS_DELAYED, ANY, ANY)
+{
+       zend_op *opline = EX(opline);
+       zend_class_entry **pce, **pce_orig;
+
+       if (zend_hash_find(EG(class_table), Z_STRVAL(opline->op2.u.constant), 
Z_STRLEN(opline->op2.u.constant)+1, (void**)&pce) == FAILURE ||
+           (zend_hash_find(EG(class_table), Z_STRVAL(opline->op1.u.constant), 
Z_STRLEN(opline->op1.u.constant), (void**)&pce_orig) == SUCCESS &&
+            *pce != *pce_orig)) {
+               do_bind_inherited_class(opline, EG(class_table), 
EX_T(opline->extended_value).class_entry, 0 TSRMLS_CC);
+       }
+       ZEND_VM_NEXT_OPCODE();
+}
+
 ZEND_VM_HANDLER(141, ZEND_DECLARE_FUNCTION, ANY, ANY)
 {
        do_bind_function(EX(opline), EG(function_table), 0);
Index: Zend/zend_vm_execute.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_execute.h,v
retrieving revision 1.62.2.30.2.49.2.41
diff -u -p -d -r1.62.2.30.2.49.2.41 zend_vm_execute.h
--- Zend/zend_vm_execute.h      12 Mar 2008 10:32:12 -0000      
1.62.2.30.2.49.2.41
+++ Zend/zend_vm_execute.h      12 Mar 2008 11:06:39 -0000
@@ -482,6 +482,19 @@ static int ZEND_DECLARE_INHERITED_CLASS_
        ZEND_VM_NEXT_OPCODE();
 }
 
+static int 
ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       zend_op *opline = EX(opline);
+       zend_class_entry **pce, **pce_orig;
+
+       if (zend_hash_find(EG(class_table), Z_STRVAL(opline->op2.u.constant), 
Z_STRLEN(opline->op2.u.constant)+1, (void**)&pce) == FAILURE ||
+           (zend_hash_find(EG(class_table), Z_STRVAL(opline->op1.u.constant), 
Z_STRLEN(opline->op1.u.constant), (void**)&pce_orig) == SUCCESS &&
+            *pce != *pce_orig)) {
+               do_bind_inherited_class(opline, EG(class_table), 
EX_T(opline->extended_value).class_entry, 0 TSRMLS_CC);
+       }
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_DECLARE_FUNCTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        do_bind_function(EX(opline), EG(function_table), 0);
@@ -32990,31 +33003,31 @@ void zend_init_opcodes_handlers(void)
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
-       ZEND_NULL_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
+       ZEND_DECLARE_INHERITED_CLASS_DELAYED_SPEC_HANDLER,
        ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
        ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
        ZEND_VERIFY_ABSTRACT_CLASS_SPEC_HANDLER,
Index: Zend/zend_vm_opcodes.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_opcodes.h,v
retrieving revision 1.42.2.17.2.1.2.4
diff -u -p -d -r1.42.2.17.2.1.2.4 zend_vm_opcodes.h
--- Zend/zend_vm_opcodes.h      31 Dec 2007 07:17:06 -0000      
1.42.2.17.2.1.2.4
+++ Zend/zend_vm_opcodes.h      12 Mar 2008 11:06:39 -0000
@@ -18,135 +18,136 @@
    +----------------------------------------------------------------------+
 */
 
-#define ZEND_NOP                       0
-#define ZEND_ADD                       1
-#define ZEND_SUB                       2
-#define ZEND_MUL                       3
-#define ZEND_DIV                       4
-#define ZEND_MOD                       5
-#define ZEND_SL                        6
-#define ZEND_SR                        7
-#define ZEND_CONCAT                    8
-#define ZEND_BW_OR                     9
-#define ZEND_BW_AND                   10
-#define ZEND_BW_XOR                   11
-#define ZEND_BW_NOT                   12
-#define ZEND_BOOL_NOT                 13
-#define ZEND_BOOL_XOR                 14
-#define ZEND_IS_IDENTICAL             15
-#define ZEND_IS_NOT_IDENTICAL         16
-#define ZEND_IS_EQUAL                 17
-#define ZEND_IS_NOT_EQUAL             18
-#define ZEND_IS_SMALLER               19
-#define ZEND_IS_SMALLER_OR_EQUAL      20
-#define ZEND_CAST                     21
-#define ZEND_QM_ASSIGN                22
-#define ZEND_ASSIGN_ADD               23
-#define ZEND_ASSIGN_SUB               24
-#define ZEND_ASSIGN_MUL               25
-#define ZEND_ASSIGN_DIV               26
-#define ZEND_ASSIGN_MOD               27
-#define ZEND_ASSIGN_SL                28
-#define ZEND_ASSIGN_SR                29
-#define ZEND_ASSIGN_CONCAT            30
-#define ZEND_ASSIGN_BW_OR             31
-#define ZEND_ASSIGN_BW_AND            32
-#define ZEND_ASSIGN_BW_XOR            33
-#define ZEND_PRE_INC                  34
-#define ZEND_PRE_DEC                  35
-#define ZEND_POST_INC                 36
-#define ZEND_POST_DEC                 37
-#define ZEND_ASSIGN                   38
-#define ZEND_ASSIGN_REF               39
-#define ZEND_ECHO                     40
-#define ZEND_PRINT                    41
-#define ZEND_JMP                      42
-#define ZEND_JMPZ                     43
-#define ZEND_JMPNZ                    44
-#define ZEND_JMPZNZ                   45
-#define ZEND_JMPZ_EX                  46
-#define ZEND_JMPNZ_EX                 47
-#define ZEND_CASE                     48
-#define ZEND_SWITCH_FREE              49
-#define ZEND_BRK                      50
-#define ZEND_CONT                     51
-#define ZEND_BOOL                     52
-#define ZEND_INIT_STRING              53
-#define ZEND_ADD_CHAR                 54
-#define ZEND_ADD_STRING               55
-#define ZEND_ADD_VAR                  56
-#define ZEND_BEGIN_SILENCE            57
-#define ZEND_END_SILENCE              58
-#define ZEND_INIT_FCALL_BY_NAME       59
-#define ZEND_DO_FCALL                 60
-#define ZEND_DO_FCALL_BY_NAME         61
-#define ZEND_RETURN                   62
-#define ZEND_RECV                     63
-#define ZEND_RECV_INIT                64
-#define ZEND_SEND_VAL                 65
-#define ZEND_SEND_VAR                 66
-#define ZEND_SEND_REF                 67
-#define ZEND_NEW                      68
-#define ZEND_INIT_NS_FCALL_BY_NAME    69
-#define ZEND_FREE                     70
-#define ZEND_INIT_ARRAY               71
-#define ZEND_ADD_ARRAY_ELEMENT        72
-#define ZEND_INCLUDE_OR_EVAL          73
-#define ZEND_UNSET_VAR                74
-#define ZEND_UNSET_DIM                75
-#define ZEND_UNSET_OBJ                76
-#define ZEND_FE_RESET                 77
-#define ZEND_FE_FETCH                 78
-#define ZEND_EXIT                     79
-#define ZEND_FETCH_R                  80
-#define ZEND_FETCH_DIM_R              81
-#define ZEND_FETCH_OBJ_R              82
-#define ZEND_FETCH_W                  83
-#define ZEND_FETCH_DIM_W              84
-#define ZEND_FETCH_OBJ_W              85
-#define ZEND_FETCH_RW                 86
-#define ZEND_FETCH_DIM_RW             87
-#define ZEND_FETCH_OBJ_RW             88
-#define ZEND_FETCH_IS                 89
-#define ZEND_FETCH_DIM_IS             90
-#define ZEND_FETCH_OBJ_IS             91
-#define ZEND_FETCH_FUNC_ARG           92
-#define ZEND_FETCH_DIM_FUNC_ARG       93
-#define ZEND_FETCH_OBJ_FUNC_ARG       94
-#define ZEND_FETCH_UNSET              95
-#define ZEND_FETCH_DIM_UNSET          96
-#define ZEND_FETCH_OBJ_UNSET          97
-#define ZEND_FETCH_DIM_TMP_VAR        98
-#define ZEND_FETCH_CONSTANT           99
-#define ZEND_EXT_STMT                101
-#define ZEND_EXT_FCALL_BEGIN         102
-#define ZEND_EXT_FCALL_END           103
-#define ZEND_EXT_NOP                 104
-#define ZEND_TICKS                   105
-#define ZEND_SEND_VAR_NO_REF         106
-#define ZEND_CATCH                   107
-#define ZEND_THROW                   108
-#define ZEND_FETCH_CLASS             109
-#define ZEND_CLONE                   110
-#define ZEND_INIT_METHOD_CALL        112
-#define ZEND_INIT_STATIC_METHOD_CALL 113
-#define ZEND_ISSET_ISEMPTY_VAR       114
-#define ZEND_ISSET_ISEMPTY_DIM_OBJ   115
-#define ZEND_PRE_INC_OBJ             132
-#define ZEND_PRE_DEC_OBJ             133
-#define ZEND_POST_INC_OBJ            134
-#define ZEND_POST_DEC_OBJ            135
-#define ZEND_ASSIGN_OBJ              136
-#define ZEND_INSTANCEOF              138
-#define ZEND_DECLARE_CLASS           139
-#define ZEND_DECLARE_INHERITED_CLASS 140
-#define ZEND_DECLARE_FUNCTION        141
-#define ZEND_RAISE_ABSTRACT_ERROR    142
-#define ZEND_DECLARE_CONST           143
-#define ZEND_ADD_INTERFACE           144
-#define ZEND_VERIFY_ABSTRACT_CLASS   146
-#define ZEND_ASSIGN_DIM              147
-#define ZEND_ISSET_ISEMPTY_PROP_OBJ  148
-#define ZEND_HANDLE_EXCEPTION        149
-#define ZEND_USER_OPCODE             150
-#define ZEND_JMP_SET                 152
+#define ZEND_NOP                               0
+#define ZEND_ADD                               1
+#define ZEND_SUB                               2
+#define ZEND_MUL                               3
+#define ZEND_DIV                               4
+#define ZEND_MOD                               5
+#define ZEND_SL                                6
+#define ZEND_SR                                7
+#define ZEND_CONCAT                            8
+#define ZEND_BW_OR                             9
+#define ZEND_BW_AND                           10
+#define ZEND_BW_XOR                           11
+#define ZEND_BW_NOT                           12
+#define ZEND_BOOL_NOT                         13
+#define ZEND_BOOL_XOR                         14
+#define ZEND_IS_IDENTICAL                     15
+#define ZEND_IS_NOT_IDENTICAL                 16
+#define ZEND_IS_EQUAL                         17
+#define ZEND_IS_NOT_EQUAL                     18
+#define ZEND_IS_SMALLER                       19
+#define ZEND_IS_SMALLER_OR_EQUAL              20
+#define ZEND_CAST                             21
+#define ZEND_QM_ASSIGN                        22
+#define ZEND_ASSIGN_ADD                       23
+#define ZEND_ASSIGN_SUB                       24
+#define ZEND_ASSIGN_MUL                       25
+#define ZEND_ASSIGN_DIV                       26
+#define ZEND_ASSIGN_MOD                       27
+#define ZEND_ASSIGN_SL                        28
+#define ZEND_ASSIGN_SR                        29
+#define ZEND_ASSIGN_CONCAT                    30
+#define ZEND_ASSIGN_BW_OR                     31
+#define ZEND_ASSIGN_BW_AND                    32
+#define ZEND_ASSIGN_BW_XOR                    33
+#define ZEND_PRE_INC                          34
+#define ZEND_PRE_DEC                          35
+#define ZEND_POST_INC                         36
+#define ZEND_POST_DEC                         37
+#define ZEND_ASSIGN                           38
+#define ZEND_ASSIGN_REF                       39
+#define ZEND_ECHO                             40
+#define ZEND_PRINT                            41
+#define ZEND_JMP                              42
+#define ZEND_JMPZ                             43
+#define ZEND_JMPNZ                            44
+#define ZEND_JMPZNZ                           45
+#define ZEND_JMPZ_EX                          46
+#define ZEND_JMPNZ_EX                         47
+#define ZEND_CASE                             48
+#define ZEND_SWITCH_FREE                      49
+#define ZEND_BRK                              50
+#define ZEND_CONT                             51
+#define ZEND_BOOL                             52
+#define ZEND_INIT_STRING                      53
+#define ZEND_ADD_CHAR                         54
+#define ZEND_ADD_STRING                       55
+#define ZEND_ADD_VAR                          56
+#define ZEND_BEGIN_SILENCE                    57
+#define ZEND_END_SILENCE                      58
+#define ZEND_INIT_FCALL_BY_NAME               59
+#define ZEND_DO_FCALL                         60
+#define ZEND_DO_FCALL_BY_NAME                 61
+#define ZEND_RETURN                           62
+#define ZEND_RECV                             63
+#define ZEND_RECV_INIT                        64
+#define ZEND_SEND_VAL                         65
+#define ZEND_SEND_VAR                         66
+#define ZEND_SEND_REF                         67
+#define ZEND_NEW                              68
+#define ZEND_INIT_NS_FCALL_BY_NAME            69
+#define ZEND_FREE                             70
+#define ZEND_INIT_ARRAY                       71
+#define ZEND_ADD_ARRAY_ELEMENT                72
+#define ZEND_INCLUDE_OR_EVAL                  73
+#define ZEND_UNSET_VAR                        74
+#define ZEND_UNSET_DIM                        75
+#define ZEND_UNSET_OBJ                        76
+#define ZEND_FE_RESET                         77
+#define ZEND_FE_FETCH                         78
+#define ZEND_EXIT                             79
+#define ZEND_FETCH_R                          80
+#define ZEND_FETCH_DIM_R                      81
+#define ZEND_FETCH_OBJ_R                      82
+#define ZEND_FETCH_W                          83
+#define ZEND_FETCH_DIM_W                      84
+#define ZEND_FETCH_OBJ_W                      85
+#define ZEND_FETCH_RW                         86
+#define ZEND_FETCH_DIM_RW                     87
+#define ZEND_FETCH_OBJ_RW                     88
+#define ZEND_FETCH_IS                         89
+#define ZEND_FETCH_DIM_IS                     90
+#define ZEND_FETCH_OBJ_IS                     91
+#define ZEND_FETCH_FUNC_ARG                   92
+#define ZEND_FETCH_DIM_FUNC_ARG               93
+#define ZEND_FETCH_OBJ_FUNC_ARG               94
+#define ZEND_FETCH_UNSET                      95
+#define ZEND_FETCH_DIM_UNSET                  96
+#define ZEND_FETCH_OBJ_UNSET                  97
+#define ZEND_FETCH_DIM_TMP_VAR                98
+#define ZEND_FETCH_CONSTANT                   99
+#define ZEND_EXT_STMT                        101
+#define ZEND_EXT_FCALL_BEGIN                 102
+#define ZEND_EXT_FCALL_END                   103
+#define ZEND_EXT_NOP                         104
+#define ZEND_TICKS                           105
+#define ZEND_SEND_VAR_NO_REF                 106
+#define ZEND_CATCH                           107
+#define ZEND_THROW                           108
+#define ZEND_FETCH_CLASS                     109
+#define ZEND_CLONE                           110
+#define ZEND_INIT_METHOD_CALL                112
+#define ZEND_INIT_STATIC_METHOD_CALL         113
+#define ZEND_ISSET_ISEMPTY_VAR               114
+#define ZEND_ISSET_ISEMPTY_DIM_OBJ           115
+#define ZEND_PRE_INC_OBJ                     132
+#define ZEND_PRE_DEC_OBJ                     133
+#define ZEND_POST_INC_OBJ                    134
+#define ZEND_POST_DEC_OBJ                    135
+#define ZEND_ASSIGN_OBJ                      136
+#define ZEND_INSTANCEOF                      138
+#define ZEND_DECLARE_CLASS                   139
+#define ZEND_DECLARE_INHERITED_CLASS         140
+#define ZEND_DECLARE_FUNCTION                141
+#define ZEND_RAISE_ABSTRACT_ERROR            142
+#define ZEND_DECLARE_CONST                   143
+#define ZEND_ADD_INTERFACE                   144
+#define ZEND_DECLARE_INHERITED_CLASS_DELAYED 145
+#define ZEND_VERIFY_ABSTRACT_CLASS           146
+#define ZEND_ASSIGN_DIM                      147
+#define ZEND_ISSET_ISEMPTY_PROP_OBJ          148
+#define ZEND_HANDLE_EXCEPTION                149
+#define ZEND_USER_OPCODE                     150
+#define ZEND_JMP_SET                         152
Index: sapi/cgi/cgi_main.c
===================================================================
RCS file: /repository/php-src/sapi/cgi/cgi_main.c,v
retrieving revision 1.267.2.15.2.50.2.13
diff -u -p -d -r1.267.2.15.2.50.2.13 cgi_main.c
--- sapi/cgi/cgi_main.c 28 Feb 2008 00:51:56 -0000      1.267.2.15.2.50.2.13
+++ sapi/cgi/cgi_main.c 12 Mar 2008 11:06:39 -0000
@@ -1691,7 +1691,7 @@ consult the installation file that came 
                                                        break;
 
                                                case 'e': /* enable extended 
info output */
-                                                       CG(extended_info) = 1;
+                                                       CG(compiler_options) |= 
ZEND_COMPILE_EXTENDED_INFO;
                                                        break;
 
                                                case 'f': /* parse file */
Index: sapi/cli/php_cli.c
===================================================================
RCS file: /repository/php-src/sapi/cli/php_cli.c,v
retrieving revision 1.129.2.13.2.22.2.4
diff -u -p -d -r1.129.2.13.2.22.2.4 php_cli.c
--- sapi/cli/php_cli.c  3 Feb 2008 17:49:46 -0000       1.129.2.13.2.22.2.4
+++ sapi/cli/php_cli.c  12 Mar 2008 11:06:40 -0000
@@ -821,7 +821,7 @@ int main(int argc, char *argv[])
                                break;
 
                        case 'e': /* enable extended info output */
-                               CG(extended_info) = 1;
+                               CG(compiler_options) |= 
ZEND_COMPILE_EXTENDED_INFO;
                                break;
 
                        case 'F':
Index: sapi/milter/php_milter.c
===================================================================
RCS file: /repository/php-src/sapi/milter/php_milter.c,v
retrieving revision 1.14.2.2.2.3.2.2
diff -u -p -d -r1.14.2.2.2.3.2.2 php_milter.c
--- sapi/milter/php_milter.c    31 Dec 2007 07:17:18 -0000      1.14.2.2.2.3.2.2
+++ sapi/milter/php_milter.c    12 Mar 2008 11:06:40 -0000
@@ -1033,7 +1033,7 @@ int main(int argc, char *argv[])
                                break;
 
                        case 'e': /* enable extended info output */
-                               CG(extended_info) = 1;
+                               CG(compiler_options) |= 
ZEND_COMPILE_EXTENDED_INFO;
                                break;
 
                        case 'f': /* parse file */
-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to