Hi,

The attached patch modifies internal ZE data structures.
It gives 4% less heap memory usage on waiting PHP process (2210KB instead of 2304KB) and up to 7% improvement on applications with many classes (ZendFramework benchmark uses 17.7M instead of 19M). It also makes small speedup on some big applications with opcode caches, because of less memory transfer.

The patch performs the following optimizations:

1) zend_function.pass_rest_by_reference is replaced by ZEND_ACC_PASS_REST_BY_REFERENCE in zend_function.fn_flags

2) zend_function.return_reference is replaced by ZEND_ACC_RETURN_REFERENCE in zend_function.fn_flags

3) zend_arg_info.required_num_args removed. it was needed only for internal functions. Now the first arg_info for internal function (which has special meaning) is represented by zend_internal_function_info structure.

4) zend_op_array.size, size_var, size_literal, current_brk_cont, backpatch_count moved into CG(context), because they are used only during compilation.

5) zend_op_array.start_op is moved into EG(start_op), because it's used
only for 'interactive' execution of single top-level op-array.

6) zend_op_array.done_pass_two is replaced by ZEND_ACC_DONE_PASS_TWO in zend_op_array.fn_flags.

7) the sise of op_array.vars is reduced during pass_two.

8) zend_class_entry.constants_updated is replaced by ZEND_ACC_CONSTANTS_UPDATED in zend_class_entry.ce_flags

9) The size of zend_class_entry is reduced by sharing the same memory space by different information for internal and user classes. See zend_class_inttry.info union.

Of course the patch will affect some extensions (e.g. APC and xdebug), but it shouldn't be difficult to fix them.

I'm going to commit the patch by the end of this week in case of no objections. I'll also add corresponding notes into UPGRADING.INTERNALS.

Thanks. Dmitry.
Index: ext/soap/soap.c
===================================================================
--- ext/soap/soap.c     (revision 303306)
+++ ext/soap/soap.c     (working copy)
@@ -703,7 +703,6 @@
                fe.prototype = NULL;
                fe.num_args = 2;
                fe.arg_info = NULL;
-               fe.pass_rest_by_reference = 0;
 
                INIT_OVERLOADED_CLASS_ENTRY(ce, PHP_SOAP_CLIENT_CLASSNAME, 
soap_client_functions,
                        (zend_function *)&fe, NULL, NULL);
Index: ext/pdo/pdo_dbh.c
===================================================================
--- ext/pdo/pdo_dbh.c   (revision 303306)
+++ ext/pdo/pdo_dbh.c   (working copy)
@@ -1308,28 +1308,36 @@
                ifunc->function_name = (char*)funcs->fname;
                ifunc->scope = dbh->std.ce;
                ifunc->prototype = NULL;
+               if (funcs->flags) {
+                       ifunc->fn_flags = funcs->flags;
+               } else {
+                       ifunc->fn_flags = ZEND_ACC_PUBLIC;
+               }
                if (funcs->arg_info) {
+                       zend_internal_function_info *info = 
(zend_internal_function_info*)funcs->arg_info;
+
                        ifunc->arg_info = (zend_arg_info*)funcs->arg_info + 1;
                        ifunc->num_args = funcs->num_args;
-                       if (funcs->arg_info[0].required_num_args == -1) {
+                       if (info->required_num_args == -1) {
                                ifunc->required_num_args = funcs->num_args;
                        } else {
-                               ifunc->required_num_args = 
funcs->arg_info[0].required_num_args;
+                               ifunc->required_num_args = 
info->required_num_args;
                        }
-                       ifunc->pass_rest_by_reference = 
funcs->arg_info[0].pass_by_reference;
-                       ifunc->return_reference = 
funcs->arg_info[0].return_reference;
+                       if (info->pass_rest_by_reference) {
+                               if (info->pass_rest_by_reference == 
ZEND_SEND_PREFER_REF) {
+                                       ifunc->fn_flags |= 
ZEND_ACC_PASS_REST_PREFER_REF;
+                               } else {
+                                       ifunc->fn_flags |= 
ZEND_ACC_PASS_REST_BY_REFERENCE;
+                               }
+                       }
+                       if (info->return_reference) {
+                               ifunc->fn_flags |= ZEND_ACC_RETURN_REFERENCE;
+                       }
                } else {
                        ifunc->arg_info = NULL;
                        ifunc->num_args = 0;
                        ifunc->required_num_args = 0;
-                       ifunc->pass_rest_by_reference = 0;
-                       ifunc->return_reference = 0;
                }
-               if (funcs->flags) {
-                       ifunc->fn_flags = funcs->flags;
-               } else {
-                       ifunc->fn_flags = ZEND_ACC_PUBLIC;
-               }
                namelen = strlen(funcs->fname);
                lc_name = emalloc(namelen+1);
                zend_str_tolower_copy(lc_name, funcs->fname, namelen);
Index: ext/reflection/php_reflection.c
===================================================================
--- ext/reflection/php_reflection.c     (revision 303306)
+++ ext/reflection/php_reflection.c     (working copy)
@@ -356,8 +356,8 @@
        string_printf(&sub_indent, "%s    ", indent);
 
        /* TBD: Repair indenting of doc comment (or is this to be done in the 
parser?) */
-       if (ce->type == ZEND_USER_CLASS && ce->doc_comment) {
-               string_printf(str, "%s%s", indent, ce->doc_comment);
+       if (ce->type == ZEND_USER_CLASS && ce->info.user.doc_comment) {
+               string_printf(str, "%s%s", indent, ce->info.user.doc_comment);
                string_write(str, "\n", 1);
        }
 
@@ -373,8 +373,8 @@
                string_printf(str, "%s%s [ ", indent, kind);
        }
        string_printf(str, (ce->type == ZEND_USER_CLASS) ? "<user" : 
"<internal");
-       if (ce->module) {
-               string_printf(str, ":%s", ce->module->name);
+       if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module) {
+               string_printf(str, ":%s", ce->info.internal.module->name);
        }
        string_printf(str, "> ");
        if (ce->get_iterator != NULL) {
@@ -414,8 +414,8 @@
 
        /* The information where a class is declared is only available for user 
classes */
        if (ce->type == ZEND_USER_CLASS) {
-               string_printf(str, "%s  @@ %s %d-%d\n", indent, ce->filename,
-                                               ce->line_start, ce->line_end);
+               string_printf(str, "%s  @@ %s %d-%d\n", indent, 
ce->info.user.filename,
+                                               ce->info.user.line_start, 
ce->info.user.line_end);
        }
 
        /* Constants */
@@ -891,7 +891,7 @@
                string_printf(str, "function ");
        }
 
-       if (fptr->op_array.return_reference) {
+       if (fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) {
                string_printf(str, "&");
        }
        string_printf(str, "%s ] {\n", fptr->common.function_name);
@@ -997,7 +997,7 @@
        struct _zend_module_entry *module = va_arg(args, struct 
_zend_module_entry*);
        int *num_classes = va_arg(args, int*);
 
-       if ((*pce)->module && !strcasecmp((*pce)->module->name, module->name)) {
+       if (((*pce)->type == ZEND_INTERNAL_CLASS) && 
(*pce)->info.internal.module && !strcasecmp((*pce)->info.internal.module->name, 
module->name)) {
                string_printf(str, "\n");
                _class_string(str, *pce, NULL, indent TSRMLS_CC);
                (*num_classes)++;
@@ -1940,7 +1940,7 @@
        METHOD_NOTSTATIC(reflection_function_abstract_ptr);
        GET_REFLECTION_OBJECT_PTR(fptr);
 
-       RETURN_BOOL(fptr->op_array.return_reference);
+       RETURN_BOOL((fptr->op_array.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0);
 }
 /* }}} */
 
@@ -3521,7 +3521,7 @@
        }
        GET_REFLECTION_OBJECT_PTR(ce);
        if (ce->type == ZEND_USER_CLASS) {
-               RETURN_STRING(ce->filename, 1);
+               RETURN_STRING(ce->info.user.filename, 1);
        }
        RETURN_FALSE;
 }
@@ -3539,7 +3539,7 @@
        }
        GET_REFLECTION_OBJECT_PTR(ce);
        if (ce->type == ZEND_USER_FUNCTION) {
-               RETURN_LONG(ce->line_start);
+               RETURN_LONG(ce->info.user.line_start);
        }
        RETURN_FALSE;
 }
@@ -3557,7 +3557,7 @@
        }
        GET_REFLECTION_OBJECT_PTR(ce);
        if (ce->type == ZEND_USER_CLASS) {
-               RETURN_LONG(ce->line_end);
+               RETURN_LONG(ce->info.user.line_end);
        }
        RETURN_FALSE;
 }
@@ -3574,8 +3574,8 @@
                return;
        }
        GET_REFLECTION_OBJECT_PTR(ce);
-       if (ce->type == ZEND_USER_CLASS && ce->doc_comment) {
-               RETURN_STRINGL(ce->doc_comment, ce->doc_comment_len, 1);
+       if (ce->type == ZEND_USER_CLASS && ce->info.user.doc_comment) {
+               RETURN_STRINGL(ce->info.user.doc_comment, 
ce->info.user.doc_comment_len, 1);
        }
        RETURN_FALSE;
 }
@@ -4548,8 +4548,8 @@
        METHOD_NOTSTATIC(reflection_class_ptr);
        GET_REFLECTION_OBJECT_PTR(ce);
 
-       if (ce->module) {
-               reflection_extension_factory(return_value, ce->module->name 
TSRMLS_CC);
+       if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module) {
+               reflection_extension_factory(return_value, 
ce->info.internal.module->name TSRMLS_CC);
        }
 }
 /* }}} */
@@ -4568,8 +4568,8 @@
        METHOD_NOTSTATIC(reflection_class_ptr);
        GET_REFLECTION_OBJECT_PTR(ce);
 
-       if (ce->module) {
-               RETURN_STRING(ce->module->name, 1);
+       if ((ce->type == ZEND_INTERNAL_CLASS) && ce->info.internal.module) {
+               RETURN_STRING(ce->info.internal.module->name, 1);
        } else {
                RETURN_FALSE;
        }
@@ -5271,7 +5271,7 @@
        struct _zend_module_entry *module = va_arg(args, struct 
_zend_module_entry*);
        int add_reflection_class = va_arg(args, int);
 
-       if ((*pce)->module && !strcasecmp((*pce)->module->name, module->name)) {
+       if (((*pce)->type == ZEND_INTERNAL_CLASS) && 
(*pce)->info.internal.module && !strcasecmp((*pce)->info.internal.module->name, 
module->name)) {
                if (add_reflection_class) {
                        ALLOC_ZVAL(zclass);
                        zend_reflection_class_factory(*pce, zclass TSRMLS_CC);
Index: Zend/zend.h
===================================================================
--- Zend/zend.h (revision 303306)
+++ Zend/zend.h (working copy)
@@ -465,7 +465,6 @@
        zend_uint name_length;
        struct _zend_class_entry *parent;
        int refcount;
-       zend_bool constants_updated;
        zend_uint ce_flags;
 
        HashTable function_table;
@@ -476,7 +475,6 @@
        HashTable constants_table;
        int default_properties_count;
        int default_static_members_count;
-       const struct _zend_function_entry *builtin_functions;
 
        union _zend_function *constructor;
        union _zend_function *destructor;
@@ -511,13 +509,19 @@
        zend_trait_alias **trait_aliases;
        zend_trait_precedence **trait_precedences;
 
-       char *filename;
-       zend_uint line_start;
-       zend_uint line_end;
-       char *doc_comment;
-       zend_uint doc_comment_len;
-
-       struct _zend_module_entry *module;
+       union {
+               struct {
+                       char *filename;
+                       zend_uint line_start;
+                       zend_uint line_end;
+                       char *doc_comment;
+                       zend_uint doc_comment_len;
+               } user;
+               struct {
+                       const struct _zend_function_entry *builtin_functions;
+                       struct _zend_module_entry *module;
+               } internal;
+       } info;
 };
 
 #include "zend_stream.h"
Index: Zend/zend_execute.c
===================================================================
--- Zend/zend_execute.c (revision 303306)
+++ Zend/zend_execute.c (working copy)
@@ -1476,7 +1476,7 @@
 ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int 
return_value_used TSRMLS_DC)
 {
        zval **return_value_ptr = &(*(temp_variable *)((char *) 
execute_data_ptr->Ts + execute_data_ptr->opline->result.var)).var.ptr;
-       ((zend_internal_function *) 
execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value,
 *return_value_ptr, 
execute_data_ptr->function_state.function->common.return_reference?return_value_ptr:NULL,
 execute_data_ptr->object, return_value_used TSRMLS_CC);
+       ((zend_internal_function *) 
execute_data_ptr->function_state.function)->handler(execute_data_ptr->opline->extended_value,
 *return_value_ptr, (execute_data_ptr->function_state.function->common.fn_flags 
& ZEND_ACC_RETURN_REFERENCE)?return_value_ptr:NULL, execute_data_ptr->object, 
return_value_used TSRMLS_CC);
 }
 
 #define ZEND_VM_NEXT_OPCODE() \
Index: Zend/zend_closures.c
===================================================================
--- Zend/zend_closures.c        (revision 303306)
+++ Zend/zend_closures.c        (working copy)
@@ -129,7 +129,7 @@
 
        invoke->common = closure->func.common;
        invoke->type = ZEND_INTERNAL_FUNCTION;
-       invoke->internal_function.fn_flags = ZEND_ACC_PUBLIC | 
ZEND_ACC_CALL_VIA_HANDLER;
+       invoke->internal_function.fn_flags = ZEND_ACC_PUBLIC | 
ZEND_ACC_CALL_VIA_HANDLER | (closure->func.common.fn_flags & 
ZEND_ACC_RETURN_REFERENCE);
        invoke->internal_function.handler = ZEND_MN(Closure___invoke);
        invoke->internal_function.module = 0;
        invoke->internal_function.scope = zend_ce_closure;
Index: Zend/zend_object_handlers.c
===================================================================
--- Zend/zend_object_handlers.c (revision 303306)
+++ Zend/zend_object_handlers.c (working copy)
@@ -938,15 +938,13 @@
 {
        zend_internal_function *call_user_call = 
emalloc(sizeof(zend_internal_function));
        call_user_call->type = ZEND_INTERNAL_FUNCTION;
-       call_user_call->module = ce->module;
+       call_user_call->module = (ce->type == ZEND_INTERNAL_CLASS) ? 
ce->info.internal.module : NULL;
        call_user_call->handler = zend_std_call_user_call;
        call_user_call->arg_info = NULL;
        call_user_call->num_args = 0;
        call_user_call->scope = ce;
        call_user_call->fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
        call_user_call->function_name = estrndup(method_name, method_len);
-       call_user_call->pass_rest_by_reference = 0;
-       call_user_call->return_reference = ZEND_RETURN_VALUE;
 
        return (union _zend_function *)call_user_call;
 }
@@ -1083,15 +1081,13 @@
 {
        zend_internal_function *callstatic_user_call = 
emalloc(sizeof(zend_internal_function));
        callstatic_user_call->type     = ZEND_INTERNAL_FUNCTION;
-       callstatic_user_call->module   = ce->module;
+       callstatic_user_call->module   = (ce->type == ZEND_INTERNAL_CLASS) ? 
ce->info.internal.module : NULL;
        callstatic_user_call->handler  = zend_std_callstatic_user_call;
        callstatic_user_call->arg_info = NULL;
        callstatic_user_call->num_args = 0;
        callstatic_user_call->scope    = ce;
        callstatic_user_call->fn_flags = ZEND_ACC_STATIC | ZEND_ACC_PUBLIC | 
ZEND_ACC_CALL_VIA_HANDLER;
        callstatic_user_call->function_name = estrndup(method_name, method_len);
-       callstatic_user_call->pass_rest_by_reference = 0;
-       callstatic_user_call->return_reference       = ZEND_RETURN_VALUE;
 
        return (zend_function *)callstatic_user_call;
 }
Index: Zend/zend_compile.c
===================================================================
--- Zend/zend_compile.c (revision 303306)
+++ Zend/zend_compile.c (working copy)
@@ -170,6 +170,16 @@
 }
 /* }}} */
 
+void zend_init_compiler_context(TSRMLS_D) /* {{{ */
+{
+       CG(context).opcodes_size = (CG(active_op_array)->fn_flags & 
ZEND_ACC_INTERACTIVE) ? INITIAL_INTERACTIVE_OP_ARRAY_SIZE : 
INITIAL_OP_ARRAY_SIZE;
+       CG(context).vars_size = 0;
+       CG(context).literals_size = 0;
+       CG(context).current_brk_cont = -1;
+       CG(context).backpatch_count = 0;
+       CG(context).labels = NULL;
+}
+/* }}} */
 
 void zend_init_compiler_data_structures(TSRMLS_D) /* {{{ */
 {
@@ -190,8 +200,7 @@
        CG(has_bracketed_namespaces) = 0;
        CG(current_import) = NULL;
        init_compiler_declarables(TSRMLS_C);
-       zend_stack_init(&CG(labels_stack));
-       CG(labels) = NULL;
+       zend_stack_init(&CG(context_stack));
 
 #ifdef ZEND_MULTIBYTE
        CG(script_encoding_list) = NULL;
@@ -238,7 +247,7 @@
        zend_stack_destroy(&CG(list_stack));
        zend_hash_destroy(&CG(filenames_table));
        zend_llist_destroy(&CG(open_files));
-       zend_stack_destroy(&CG(labels_stack));
+       zend_stack_destroy(&CG(context_stack));
 
 #ifdef ZEND_MULTIBYTE
        if (CG(script_encoding_list)) {
@@ -317,9 +326,9 @@
        }
        i = op_array->last_var;
        op_array->last_var++;
-       if (op_array->last_var > op_array->size_var) {
-               op_array->size_var += 16; /* FIXME */
-               op_array->vars = erealloc(op_array->vars, 
op_array->size_var*sizeof(zend_compiled_variable));
+       if (op_array->last_var > CG(context).vars_size) {
+               CG(context).vars_size += 16; /* FIXME */
+               op_array->vars = erealloc(op_array->vars, CG(context).vars_size 
* sizeof(zend_compiled_variable));
        }
        op_array->vars[i].name = zend_new_interned_string(name, name_len + 1, 1 
TSRMLS_CC);
        op_array->vars[i].name_len = name_len;
@@ -343,9 +352,9 @@
 {
        int i = op_array->last_literal;
        op_array->last_literal++;
-       if (i >= op_array->size_literal) {
-               op_array->size_literal += 16; /* FIXME */
-               op_array->literals = 
(zend_literal*)erealloc(op_array->literals, op_array->size_literal * 
sizeof(zend_literal));
+       if (i >= CG(context).literals_size) {
+               CG(context).literals_size += 16; /* FIXME */
+               op_array->literals = 
(zend_literal*)erealloc(op_array->literals, CG(context).literals_size * 
sizeof(zend_literal));
        }
        if (Z_TYPE_P(zv) == IS_STRING || Z_TYPE_P(zv) == IS_CONSTANT) {
                zval *z = (zval*)zv;
@@ -1049,8 +1058,8 @@
        zend_brk_cont_element *brk_cont_element;
        int parent;
 
-       parent = CG(active_op_array)->current_brk_cont;
-       CG(active_op_array)->current_brk_cont = 
CG(active_op_array)->last_brk_cont;
+       parent = CG(context).current_brk_cont;
+       CG(context).current_brk_cont = CG(active_op_array)->last_brk_cont;
        brk_cont_element = get_next_brk_cont_element(CG(active_op_array));
        brk_cont_element->start = get_next_op_number(CG(active_op_array));
        brk_cont_element->parent = parent;
@@ -1063,11 +1072,11 @@
                /* The start fileld is used to free temporary variables in case 
of exceptions.
                 * We won't try to free something of we don't have loop 
variable.
                 */
-               
CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].start
 = -1;
+               
CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].start = -1;
        }
-       
CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].cont 
= cont_addr;
-       
CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].brk 
= get_next_op_number(CG(active_op_array));
-       CG(active_op_array)->current_brk_cont = 
CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].parent;
+       CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].cont 
= cont_addr;
+       CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].brk = 
get_next_op_number(CG(active_op_array));
+       CG(context).current_brk_cont = 
CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].parent;
 }
 /* }}} */
 
@@ -1539,9 +1548,10 @@
        CG(interactive) = orig_interactive;
 
        op_array.function_name = name;
-       op_array.return_reference = return_reference;
+       if (return_reference) {
+               op_array.fn_flags |= ZEND_ACC_RETURN_REFERENCE;
+       }
        op_array.fn_flags |= fn_flags;
-       op_array.pass_rest_by_reference = 0;
 
        op_array.scope = is_method?CG(active_class_entry):NULL;
        op_array.prototype = NULL;
@@ -1555,6 +1565,9 @@
                        zend_error(E_COMPILE_ERROR, "Cannot redeclare 
%s::%s()", CG(active_class_entry)->name, name);
                }
 
+               zend_stack_push(&CG(context_stack), (void *) &CG(context), 
sizeof(CG(context)));
+               zend_init_compiler_context(TSRMLS_C);
+
                if (fn_flags & ZEND_ACC_ABSTRACT) {
                        CG(active_class_entry)->ce_flags |= 
ZEND_ACC_IMPLICIT_ABSTRACT_CLASS;
                }
@@ -1683,6 +1696,8 @@
                CALCULATE_LITERAL_HASH(opline->op2.constant);
                opline->extended_value = ZEND_DECLARE_FUNCTION;
                zend_hash_quick_update(CG(function_table), Z_STRVAL(key), 
Z_STRLEN(key), Z_HASH_P(&CONSTANT(opline->op1.constant)), &op_array, 
sizeof(zend_op_array), (void **) &CG(active_op_array));
+               zend_stack_push(&CG(context_stack), (void *) &CG(context), 
sizeof(CG(context)));
+               zend_init_compiler_context(TSRMLS_C);
        }
 
        if (CG(compiler_options) & ZEND_COMPILE_EXTENDED_INFO) {
@@ -1721,9 +1736,6 @@
                CG(doc_comment) = NULL;
                CG(doc_comment_len) = 0;
        }
-
-       zend_stack_push(&CG(labels_stack), (void *) &CG(labels), 
sizeof(HashTable*));
-       CG(labels) = NULL;
 }
 /* }}} */
 
@@ -2225,18 +2237,17 @@
 
 void zend_do_label(znode *label TSRMLS_DC) /* {{{ */
 {
-       zend_op_array *oparray = CG(active_op_array);
        zend_label dest;
 
-       if (!CG(labels)) {
-               ALLOC_HASHTABLE(CG(labels));
-               zend_hash_init(CG(labels), 4, NULL, NULL, 0);
+       if (!CG(context).labels) {
+               ALLOC_HASHTABLE(CG(context).labels);
+               zend_hash_init(CG(context).labels, 4, NULL, NULL, 0);
        }
 
-       dest.brk_cont = oparray->current_brk_cont;
-       dest.opline_num = get_next_op_number(oparray);
+       dest.brk_cont = CG(context).current_brk_cont;
+       dest.opline_num = get_next_op_number(CG(active_op_array));
 
-       if (zend_hash_add(CG(labels), Z_STRVAL(label->u.constant), 
Z_STRLEN(label->u.constant) + 1, (void**)&dest, sizeof(zend_label), NULL) == 
FAILURE) {
+       if (zend_hash_add(CG(context).labels, Z_STRVAL(label->u.constant), 
Z_STRLEN(label->u.constant) + 1, (void**)&dest, sizeof(zend_label), NULL) == 
FAILURE) {
                zend_error(E_COMPILE_ERROR, "Label '%s' already defined", 
Z_STRVAL(label->u.constant));
        }
 
@@ -2256,8 +2267,8 @@
        } else {
                label = &CONSTANT_EX(op_array, opline->op2.constant);
        }
-       if (CG(labels) == NULL ||
-           zend_hash_find(CG(labels), Z_STRVAL_P(label), Z_STRLEN_P(label)+1, 
(void**)&dest) == FAILURE) {
+       if (CG(context).labels == NULL ||
+           zend_hash_find(CG(context).labels, Z_STRVAL_P(label), 
Z_STRLEN_P(label)+1, (void**)&dest) == FAILURE) {
 
            if (pass2) {
                CG(in_compilation) = 1;
@@ -2310,7 +2321,7 @@
        zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 
        opline->opcode = ZEND_GOTO;
-       opline->extended_value = CG(active_op_array)->current_brk_cont;
+       opline->extended_value = CG(context).current_brk_cont;
        SET_UNUSED(opline->op1);
        SET_NODE(opline->op2, label);
        zend_resolve_goto_label(CG(active_op_array), opline, 0 TSRMLS_CC);
@@ -2319,18 +2330,16 @@
 
 void zend_release_labels(TSRMLS_D) /* {{{ */
 {
-       if (CG(labels)) {
-               zend_hash_destroy(CG(labels));
-               FREE_HASHTABLE(CG(labels));
+       if (CG(context).labels) {
+               zend_hash_destroy(CG(context).labels);
+               FREE_HASHTABLE(CG(context).labels);
        }
-       if (!zend_stack_is_empty(&CG(labels_stack))) {
-               HashTable **pht;
+       if (!zend_stack_is_empty(&CG(context_stack))) {
+               zend_compiler_context *ctx;
 
-               zend_stack_top(&CG(labels_stack), (void**)&pht);
-               CG(labels) = *pht;
-               zend_stack_del_top(&CG(labels_stack));
-       } else {
-               CG(labels) = NULL;
+               zend_stack_top(&CG(context_stack), (void**)&ctx);
+               CG(context) = *ctx;
+               zend_stack_del_top(&CG(context_stack));
        }
 }
 /* }}} */
@@ -2611,7 +2620,7 @@
        int start_op_number, end_op_number;
 
        if (do_end_vparse) {
-               if (CG(active_op_array)->return_reference && 
!zend_is_function_or_method_call(expr)) {
+               if ((CG(active_op_array)->fn_flags & ZEND_ACC_RETURN_REFERENCE) 
&& !zend_is_function_or_method_call(expr)) {
                        zend_do_end_variable_parse(expr, BP_VAR_W, 0 TSRMLS_CC);
                } else {
                        zend_do_end_variable_parse(expr, BP_VAR_R, 0 TSRMLS_CC);
@@ -2636,7 +2645,7 @@
 
        opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 
-       opline->opcode = (CG(active_op_array)->return_reference == 
ZEND_RETURN_REF) ? ZEND_RETURN_BY_REF : ZEND_RETURN;
+       opline->opcode = (CG(active_op_array)->fn_flags & 
ZEND_ACC_RETURN_REFERENCE) ? ZEND_RETURN_BY_REF : ZEND_RETURN;
 
        if (expr) {
                SET_NODE(opline->op1, expr);
@@ -2942,12 +2951,13 @@
        }
 
        if (fe->common.type != ZEND_USER_FUNCTION
-               && proto->common.pass_rest_by_reference
-               && !fe->common.pass_rest_by_reference) {
+               && (proto->common.fn_flags & ZEND_ACC_PASS_REST_BY_REFERENCE) 
!= 0
+               && (fe->common.fn_flags & ZEND_ACC_PASS_REST_BY_REFERENCE) == 
0) {
                return 0;
        }
 
-       if (fe->common.return_reference != proto->common.return_reference) {
+       if ((fe->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) !=
+           (proto->common.fn_flags & ZEND_ACC_RETURN_REFERENCE)) {
                return 0;
        }
 
@@ -2976,7 +2986,7 @@
                }
        }
 
-       if (proto->common.pass_rest_by_reference) {
+       if (proto->common.fn_flags & ZEND_ACC_PASS_REST_BY_REFERENCE) {
                for (i=proto->common.num_args; i < fe->common.num_args; i++) {
                        if (!fe->common.arg_info[i].pass_by_reference) {
                                return 0;
@@ -3543,7 +3553,6 @@
                }
        }
        fe->op_array.opcodes = opcode_copy;
-       fe->op_array.start_op = fe->op_array.opcodes;
        fe->op_array.function_name = newname;
 
        /* was setting it to fe which does not work since fe is stack allocated 
and not a stable address */
@@ -3570,9 +3579,9 @@
        fe->op_array.brk_cont_array = 
(zend_brk_cont_element*)estrndup((char*)fe->op_array.brk_cont_array, 
sizeof(zend_brk_cont_element) * fe->op_array.last_brk_cont);
   
        /* TODO: check whether there is something similar and whether that is 
ok */
-       literals_copy = (zend_literal*)emalloc(fe->op_array.size_literal * 
sizeof(zend_literal));
+       literals_copy = (zend_literal*)emalloc(fe->op_array.last_literal * 
sizeof(zend_literal));
   
-       for (i = 0; i < fe->op_array.size_literal; i++) {
+       for (i = 0; i < fe->op_array.last_literal; i++) {
                literals_copy[i] = fe->op_array.literals[i];
                zval_copy_ctor(&literals_copy[i].constant);
        }
@@ -4320,7 +4329,7 @@
        zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 
        opline->opcode = op;
-       opline->op1.opline_num = CG(active_op_array)->current_brk_cont;
+       opline->op1.opline_num = CG(context).current_brk_cont;
        SET_UNUSED(opline->op1);
        if (expr) {
                SET_NODE(opline->op2, expr);
@@ -4369,8 +4378,8 @@
        }
 
        /* remember break/continue loop information */
-       
CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].cont 
= 
CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].brk 
= get_next_op_number(CG(active_op_array));
-       CG(active_op_array)->current_brk_cont = 
CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].parent;
+       CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].cont 
= CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].brk = 
get_next_op_number(CG(active_op_array));
+       CG(context).current_brk_cont = 
CG(active_op_array)->brk_cont_array[CG(context).current_brk_cont].parent;
 
        if (switch_entry_ptr->cond.op_type==IS_VAR || 
switch_entry_ptr->cond.op_type==IS_TMP_VAR) {
                /* emit free for the switch condition*/
@@ -4525,8 +4534,8 @@
        new_class_entry->name_length = Z_STRLEN(class_name->u.constant);
 
        zend_initialize_class_data(new_class_entry, 1 TSRMLS_CC);
-       new_class_entry->filename = zend_get_compiled_filename(TSRMLS_C);
-       new_class_entry->line_start = class_token->u.op.opline_num;
+       new_class_entry->info.user.filename = 
zend_get_compiled_filename(TSRMLS_C);
+       new_class_entry->info.user.line_start = class_token->u.op.opline_num;
        new_class_entry->ce_flags |= class_token->EA;
 
        if (parent_class_name && parent_class_name->op_type != IS_UNUSED) {
@@ -4572,8 +4581,8 @@
        GET_NODE(&CG(implementing_class), opline->result);
 
        if (CG(doc_comment)) {
-               CG(active_class_entry)->doc_comment = CG(doc_comment);
-               CG(active_class_entry)->doc_comment_len = CG(doc_comment_len);
+               CG(active_class_entry)->info.user.doc_comment = CG(doc_comment);
+               CG(active_class_entry)->info.user.doc_comment_len = 
CG(doc_comment_len);
                CG(doc_comment) = NULL;
                CG(doc_comment_len) = 0;
        }
@@ -4613,7 +4622,7 @@
                }
        }
 
-       ce->line_end = zend_get_compiled_lineno(TSRMLS_C);
+       ce->info.user.line_end = zend_get_compiled_lineno(TSRMLS_C);
        
        /* Check for traits and proceed like with interfaces.
         * The only difference will be a combined handling of them in the end.
@@ -6205,12 +6214,8 @@
        dtor_func_t zval_ptr_dtor_func = ((persistent_hashes) ? 
ZVAL_INTERNAL_PTR_DTOR : ZVAL_PTR_DTOR);
 
        ce->refcount = 1;
-       ce->constants_updated = 0;
        ce->ce_flags = 0;
 
-       ce->doc_comment = NULL;
-       ce->doc_comment_len = 0;
-
        ce->default_properties_table = NULL;
        ce->default_static_members_table = NULL;
        zend_hash_init_ex(&ce->properties_info, 0, NULL, (dtor_func_t) 
(persistent_hashes ? zend_destroy_property_info_internal : 
zend_destroy_property_info), persistent_hashes, 0);
@@ -6233,6 +6238,8 @@
 #endif
        } else {
                ce->static_members_table = ce->default_static_members_table;
+               ce->info.user.doc_comment = NULL;
+               ce->info.user.doc_comment_len = 0;
        }
 
        ce->default_properties_count = 0;
@@ -6261,12 +6268,14 @@
                ce->traits = NULL;
                ce->trait_aliases = NULL;
                ce->trait_precedences = NULL;
-               ce->module = NULL;
                ce->serialize = NULL;
                ce->unserialize = NULL;
                ce->serialize_func = NULL;
                ce->unserialize_func = NULL;
-               ce->builtin_functions = NULL;
+               if (ce->type == ZEND_INTERNAL_CLASS) {
+                       ce->info.internal.module = NULL;
+                       ce->info.internal.builtin_functions = NULL;
+               }
        }
 }
 /* }}} */
@@ -6456,7 +6465,7 @@
                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)->filename == CG(compiled_filename)) {
+                  (*pce)->info.user.filename == CG(compiled_filename)) {
                char *c_tmp = zend_str_tolower_dup(Z_STRVAL_P(ns), 
Z_STRLEN_P(ns));
 
                if (Z_STRLEN_P(ns) != Z_STRLEN_P(name) ||
Index: Zend/zend_compile.h
===================================================================
--- Zend/zend_compile.h (revision 303306)
+++ Zend/zend_compile.h (working copy)
@@ -36,8 +36,8 @@
 
 #define SET_UNUSED(op)  op ## _type = IS_UNUSED
 
-#define INC_BPC(op_array)      if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) 
{ ((op_array)->backpatch_count++); }
-#define DEC_BPC(op_array)      if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) 
{ ((op_array)->backpatch_count--); }
+#define INC_BPC(op_array)      if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) 
{ (CG(context).backpatch_count++); }
+#define DEC_BPC(op_array)      if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) 
{ (CG(context).backpatch_count--); }
 #define HANDLE_INTERACTIVE()  if (CG(active_op_array)->fn_flags & 
ZEND_ACC_INTERACTIVE) { execute_new_code(TSRMLS_C); }
 
 #define RESET_DOC_COMMENT()        \
@@ -52,6 +52,15 @@
 typedef struct _zend_op_array zend_op_array;
 typedef struct _zend_op zend_op;
 
+typedef struct _zend_compiler_context {
+       zend_uint  opcodes_size;
+       int        vars_size;
+       int        literals_size;
+       int        current_brk_cont;
+       int        backpatch_count;
+       HashTable *labels;
+} zend_compiler_context;
+
 typedef struct _zend_literal {
        zval       constant;
        zend_ulong hash_value;
@@ -171,6 +180,9 @@
 #define ZEND_ACC_IMPLEMENT_INTERFACES 0x80000
 #define ZEND_ACC_IMPLEMENT_TRAITS        0x400000
 
+/* class constants updated */
+#define ZEND_ACC_CONSTANTS_UPDATED       0x100000
+
 /* user class has methods with static variables */
 #define ZEND_HAS_STATIC_IN_METHODS    0x800000
 
@@ -180,6 +192,12 @@
 /* function flag for internal user call handlers __call, __callstatic */
 #define ZEND_ACC_CALL_VIA_HANDLER     0x200000
 
+#define ZEND_ACC_PASS_REST_BY_REFERENCE 0x1000000
+#define ZEND_ACC_PASS_REST_PREFER_REF  0x2000000
+
+#define ZEND_ACC_RETURN_REFERENCE              0x4000000
+#define ZEND_ACC_DONE_PASS_TWO                 0x8000000
+
 char *zend_visibility_string(zend_uint fn_flags);
 
 
@@ -203,10 +221,22 @@
        zend_uchar type_hint;
        zend_bool allow_null;
        zend_bool pass_by_reference;
-       zend_bool return_reference;
-       int required_num_args;
 } zend_arg_info;
 
+/* the following structure repeats the layout of zend_arg_info,
+ * but its fields have different meaning. It's used as the first element of 
+ * arg_info array to define properties of internal functions.
+ */
+typedef struct _zend_internal_function_info {
+       const char *_name;
+       zend_uint _name_len;
+       const char *_class_name;
+       zend_uint required_num_args;
+       zend_uchar _type_hint;
+       zend_bool return_reference;
+       zend_bool pass_rest_by_reference;
+} zend_internal_function_info;
+
 typedef struct _zend_compiled_variable {
        char *name;
        int name_len;
@@ -223,25 +253,20 @@
        zend_uint num_args;
        zend_uint required_num_args;
        zend_arg_info *arg_info;
-       zend_bool pass_rest_by_reference;
-       unsigned char return_reference;
        /* END of common elements */
 
-       zend_bool done_pass_two;
-
        zend_uint *refcount;
 
        zend_op *opcodes;
-       zend_uint last, size;
+       zend_uint last;
 
        zend_compiled_variable *vars;
-       int last_var, size_var;
+       int last_var;
 
        zend_uint T;
 
        zend_brk_cont_element *brk_cont_array;
        int last_brk_cont;
-       int current_brk_cont;
 
        zend_try_catch_element *try_catch_array;
        int last_try_catch;
@@ -249,9 +274,6 @@
        /* static variables support */
        HashTable *static_variables;
 
-       zend_op *start_op;
-       int backpatch_count;
-
        zend_uint this_var;
 
        char *filename;
@@ -262,7 +284,7 @@
        zend_uint early_binding; /* the linked list of delayed declarations */
 
        zend_literal *literals;
-       int last_literal, size_literal;
+       int last_literal;
 
        void **run_time_cache;
        int  last_cache_slot;
@@ -284,8 +306,6 @@
        zend_uint num_args;
        zend_uint required_num_args;
        zend_arg_info *arg_info;
-       zend_bool pass_rest_by_reference;
-       unsigned char return_reference;
        /* END of common elements */
 
        void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
@@ -306,8 +326,6 @@
                zend_uint num_args;
                zend_uint required_num_args;
                zend_arg_info *arg_info;
-               zend_bool pass_rest_by_reference;
-               unsigned char return_reference;
        } common;
 
        zend_op_array op_array;
@@ -374,6 +392,7 @@
 void init_compiler(TSRMLS_D);
 void shutdown_compiler(TSRMLS_D);
 void zend_init_compiler_data_structures(TSRMLS_D);
+void zend_init_compiler_context(TSRMLS_D);
 
 extern ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle 
*file_handle, int type TSRMLS_DC);
 extern ZEND_API zend_op_array *(*zend_compile_string)(zval *source_string, 
char *filename TSRMLS_DC);
@@ -602,6 +621,7 @@
 ZEND_API void function_add_ref(zend_function *function);
 
 #define INITIAL_OP_ARRAY_SIZE 64
+#define INITIAL_INTERACTIVE_OP_ARRAY_SIZE 8192
 
 
 /* helper functions in zend_language_scanner.l */
@@ -766,22 +786,21 @@
 #define ZEND_SEND_BY_REF     1
 #define ZEND_SEND_PREFER_REF 2
 
-#define ARG_SEND_TYPE(zf, arg_num)                                             
                                                \
-       ((zf) ?                                                                 
    \
-        ((((zend_function*)(zf))->common.arg_info &&                           
    \
-          arg_num<=((zend_function*)(zf))->common.num_args) ?                  
    \
-         ((zend_function *)(zf))->common.arg_info[arg_num-1].pass_by_reference 
:   \
-         ((zend_function *)(zf))->common.pass_rest_by_reference) :             
    \
-        ZEND_SEND_BY_VAL)      
+#define CHECK_ARG_SEND_TYPE(zf, arg_num, m1, m2)                               
                                                        \
+       ((zf) &&                                                                
                                                                                
                \
+         ((((zend_function*)(zf))->common.arg_info &&                          
                                                        \
+           arg_num <= ((zend_function*)(zf))->common.num_args) ?               
                                                \
+          (((zend_function 
*)(zf))->common.arg_info[arg_num-1].pass_by_reference & (m1)) :             \
+       (((zend_function *)(zf))->common.fn_flags & (m2))))
 
 #define ARG_MUST_BE_SENT_BY_REF(zf, arg_num) \
-       (ARG_SEND_TYPE(zf, arg_num) == ZEND_SEND_BY_REF)
+       CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF, 
ZEND_ACC_PASS_REST_BY_REFERENCE)
 
 #define ARG_SHOULD_BE_SENT_BY_REF(zf, arg_num) \
-       (ARG_SEND_TYPE(zf, arg_num) & (ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF))
+       CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF, 
ZEND_ACC_PASS_REST_BY_REFERENCE|ZEND_ACC_PASS_REST_PREFER_REF)
 
 #define ARG_MAY_BE_SENT_BY_REF(zf, arg_num) \
-       (ARG_SEND_TYPE(zf, arg_num) == ZEND_SEND_PREFER_REF)
+       CHECK_ARG_SEND_TYPE(zf, arg_num, ZEND_SEND_PREFER_REF, 
ZEND_ACC_PASS_REST_PREFER_REF)
 
 #define ZEND_RETURN_VAL 0
 #define ZEND_RETURN_REF 1
Index: Zend/zend_vm_def.h
===================================================================
--- Zend/zend_vm_def.h  (revision 303306)
+++ Zend/zend_vm_def.h  (working copy)
@@ -2578,7 +2578,7 @@
                MAKE_STD_ZVAL(ret->var.ptr);
                ZVAL_NULL(ret->var.ptr);
                ret->var.ptr_ptr = &ret->var.ptr;
-               ret->var.fcall_returned_reference = 
fbc->common.return_reference;
+               ret->var.fcall_returned_reference = (fbc->common.fn_flags & 
ZEND_ACC_RETURN_REFERENCE) != 0;
 
                if (fbc->common.arg_info) {
                        zend_uint i=0;
@@ -2593,7 +2593,7 @@
 
                if (!zend_execute_internal) {
                        /* saves one function call if zend_execute_internal is 
not used */
-                       fbc->internal_function.handler(opline->extended_value, 
ret->var.ptr, fbc->common.return_reference ? &ret->var.ptr : NULL, EX(object), 
RETURN_VALUE_USED(opline) TSRMLS_CC);
+                       fbc->internal_function.handler(opline->extended_value, 
ret->var.ptr, (fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) ? 
&ret->var.ptr : NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
                } else {
                        zend_execute_internal(EXECUTE_DATA, 
RETURN_VALUE_USED(opline) TSRMLS_CC);
                }
@@ -2612,7 +2612,7 @@
                        ret->var.ptr = NULL;
                        EG(return_value_ptr_ptr) = &ret->var.ptr;
                        ret->var.ptr_ptr = &ret->var.ptr;
-                       ret->var.fcall_returned_reference = 
fbc->common.return_reference;
+                       ret->var.fcall_returned_reference = 
(fbc->common.fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0;
                }
 
                if (EXPECTED(zend_execute == execute)) {
Index: Zend/zend_vm_execute.skl
===================================================================
--- Zend/zend_vm_execute.skl    (revision 303306)
+++ Zend/zend_vm_execute.skl    (working copy)
@@ -55,7 +55,7 @@
                }
        }
 
-       EX(opline) = op_array->start_op ? op_array->start_op : 
op_array->opcodes;
+       EX(opline) = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 
0) && EG(start_op) ? EG(start_op) : op_array->opcodes;
        EG(opline_ptr) = &EX(opline);
        LOAD_OPLINE();
 
Index: Zend/zend_language_scanner.l
===================================================================
--- Zend/zend_language_scanner.l        (revision 303306)
+++ Zend/zend_language_scanner.l        (working copy)
@@ -351,6 +351,7 @@
                init_op_array(op_array, ZEND_USER_FUNCTION, 
INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
                CG(in_compilation) = 1;
                CG(active_op_array) = op_array;
+               zend_init_compiler_context(TSRMLS_C);
                compiler_result = zendparse(TSRMLS_C);
                zend_do_return(&retval_znode, 0 TSRMLS_CC);
                CG(in_compilation) = original_in_compilation;
@@ -515,6 +516,7 @@
                init_op_array(op_array, ZEND_EVAL_CODE, INITIAL_OP_ARRAY_SIZE 
TSRMLS_CC);
                CG(interactive) = orig_interactive;
                CG(active_op_array) = op_array;
+               zend_init_compiler_context(TSRMLS_C);
                BEGIN(ST_IN_SCRIPTING);
                compiler_result = zendparse(TSRMLS_C);
 
Index: Zend/zend_API.c
===================================================================
--- Zend/zend_API.c     (revision 303306)
+++ Zend/zend_API.c     (working copy)
@@ -1015,7 +1015,7 @@
 
 ZEND_API void zend_update_class_constants(zend_class_entry *class_type 
TSRMLS_DC) /* {{{ */
 {
-       if (!class_type->constants_updated || (!CE_STATIC_MEMBERS(class_type) 
&& class_type->default_static_members_count)) {
+       if ((class_type->ce_flags & ZEND_ACC_CONSTANTS_UPDATED) == 0 || 
(!CE_STATIC_MEMBERS(class_type) && class_type->default_static_members_count)) {
                zend_class_entry **scope = 
EG(in_execution)?&EG(scope):&CG(active_class_entry);
                zend_class_entry *old_scope = *scope;
                int i;
@@ -1070,7 +1070,7 @@
                }
 
                *scope = old_scope;
-               class_type->constants_updated = 1;
+               class_type->ce_flags |= ZEND_ACC_CONSTANTS_UPDATED;
        }
 }
 /* }}} */
@@ -1953,36 +1953,44 @@
                internal_function->function_name = (char*)ptr->fname;
                internal_function->scope = scope;
                internal_function->prototype = NULL;
+               if (ptr->flags) {
+                       if (!(ptr->flags & ZEND_ACC_PPP_MASK)) {
+                               if (ptr->flags != ZEND_ACC_DEPRECATED || scope) 
{
+                                       zend_error(error_type, "Invalid access 
level for %s%s%s() - access must be exactly one of public, protected or 
private", scope ? scope->name : "", scope ? "::" : "", ptr->fname);
+                               }
+                               internal_function->fn_flags = ZEND_ACC_PUBLIC | 
ptr->flags;
+                       } else {
+                               internal_function->fn_flags = ptr->flags;
+                       }
+               } else {
+                       internal_function->fn_flags = ZEND_ACC_PUBLIC;
+               }
                if (ptr->arg_info) {
+                       zend_internal_function_info *info = 
(zend_internal_function_info*)ptr->arg_info;
+                       
                        internal_function->arg_info = 
(zend_arg_info*)ptr->arg_info+1;
                        internal_function->num_args = ptr->num_args;
                        /* Currently you cannot denote that the function can 
accept less arguments than num_args */
-                       if (ptr->arg_info[0].required_num_args == -1) {
+                       if (info->required_num_args == -1) {
                                internal_function->required_num_args = 
ptr->num_args;
                        } else {
-                               internal_function->required_num_args = 
ptr->arg_info[0].required_num_args;
+                               internal_function->required_num_args = 
info->required_num_args;
                        }
-                       internal_function->pass_rest_by_reference = 
ptr->arg_info[0].pass_by_reference;
-                       internal_function->return_reference = 
ptr->arg_info[0].return_reference;
+                       if (info->pass_rest_by_reference) {
+                               if (info->pass_rest_by_reference == 
ZEND_SEND_PREFER_REF) {
+                                       internal_function->fn_flags |= 
ZEND_ACC_PASS_REST_PREFER_REF;
+                               } else {
+                                       internal_function->fn_flags |= 
ZEND_ACC_PASS_REST_BY_REFERENCE;
+                               }
+                       }
+                       if (info->return_reference) {
+                               internal_function->fn_flags |= 
ZEND_ACC_RETURN_REFERENCE;
+                       }
                } else {
                        internal_function->arg_info = NULL;
                        internal_function->num_args = 0;
                        internal_function->required_num_args = 0;
-                       internal_function->pass_rest_by_reference = 0;
-                       internal_function->return_reference = 0;
                }
-               if (ptr->flags) {
-                       if (!(ptr->flags & ZEND_ACC_PPP_MASK)) {
-                               if (ptr->flags != ZEND_ACC_DEPRECATED || scope) 
{
-                                       zend_error(error_type, "Invalid access 
level for %s%s%s() - access must be exactly one of public, protected or 
private", scope ? scope->name : "", scope ? "::" : "", ptr->fname);
-                               }
-                               internal_function->fn_flags = ZEND_ACC_PUBLIC | 
ptr->flags;
-                       } else {
-                               internal_function->fn_flags = ptr->flags;
-                       }
-               } else {
-                       internal_function->fn_flags = ZEND_ACC_PUBLIC;
-               }
                if (ptr->flags & ZEND_ACC_ABSTRACT) {
                        if (scope) {
                                /* This is a class that must be abstract 
itself. Here we set the check info. */
@@ -2353,10 +2361,10 @@
        class_entry->type = ZEND_INTERNAL_CLASS;
        zend_initialize_class_data(class_entry, 0 TSRMLS_CC);
        class_entry->ce_flags = ce_flags;
-       class_entry->module = EG(current_module);
+       class_entry->info.internal.module = EG(current_module);
 
-       if (class_entry->builtin_functions) {
-               zend_register_functions(class_entry, 
class_entry->builtin_functions, &class_entry->function_table, MODULE_PERSISTENT 
TSRMLS_CC);
+       if (class_entry->info.internal.builtin_functions) {
+               zend_register_functions(class_entry, 
class_entry->info.internal.builtin_functions, &class_entry->function_table, 
MODULE_PERSISTENT TSRMLS_CC);
        }
 
        zend_str_tolower_copy(lowercase_name, orig_class_entry->name, 
class_entry->name_length);
@@ -2712,15 +2720,13 @@
                        if (strict_class && ce_org->__call) {
                                fcc->function_handler = 
emalloc(sizeof(zend_internal_function));
                                fcc->function_handler->internal_function.type = 
ZEND_INTERNAL_FUNCTION;
-                               fcc->function_handler->internal_function.module 
= ce_org->module;
+                               fcc->function_handler->internal_function.module 
= (ce_org->type == ZEND_INTERNAL_CLASS) ? ce_org->info.internal.module : NULL;
                                
fcc->function_handler->internal_function.handler = zend_std_call_user_call;
                                
fcc->function_handler->internal_function.arg_info = NULL;
                                
fcc->function_handler->internal_function.num_args = 0;
                                fcc->function_handler->internal_function.scope 
= ce_org;
                                
fcc->function_handler->internal_function.fn_flags = ZEND_ACC_CALL_VIA_HANDLER;
                                
fcc->function_handler->internal_function.function_name = estrndup(mname, mlen);
-                               
fcc->function_handler->internal_function.pass_rest_by_reference = 0;
-                               
fcc->function_handler->internal_function.return_reference = ZEND_RETURN_VALUE;
                                call_via_handler = 1;
                                retval = 1;
                        } else if (Z_OBJ_HT_P(fcc->object_ptr)->get_method) {
Index: Zend/zend_API.h
===================================================================
--- Zend/zend_API.h     (revision 303306)
+++ Zend/zend_API.h     (working copy)
@@ -96,14 +96,14 @@
 #define ZEND_NS_FALIAS(ns, name, alias, arg_info)              
ZEND_NS_FENTRY(ns, name, ZEND_FN(alias), arg_info, 0)
 #define ZEND_NS_DEP_FALIAS(ns, name, alias, arg_info)  ZEND_NS_FENTRY(ns, 
name, ZEND_FN(alias), arg_info, ZEND_ACC_DEPRECATED)
 
-#define ZEND_ARG_INFO(pass_by_ref, name)                                       
                { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },
-#define ZEND_ARG_PASS_INFO(pass_by_ref)                                        
                        { NULL, 0, NULL, 0, 0, 0, pass_by_ref, 0, 0 },
-#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, 
sizeof(#name)-1, #classname, sizeof(#classname)-1, IS_CLASS, allow_null, 
pass_by_ref, 0, 0 },
-#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, 
sizeof(#name)-1, NULL, 0, IS_ARRAY, allow_null, pass_by_ref, 0, 0 },
-#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, 
sizeof(#name)-1, NULL, 0, type_hint, allow_null, pass_by_ref, 0, 0 },
+#define ZEND_ARG_INFO(pass_by_ref, name)                                       
                { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref},
+#define ZEND_ARG_PASS_INFO(pass_by_ref)                                        
                        { NULL, 0, NULL, 0, 0, 0, pass_by_ref},
+#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, 
sizeof(#name)-1, #classname, sizeof(#classname)-1, IS_CLASS, allow_null, 
pass_by_ref},
+#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, 
sizeof(#name)-1, NULL, 0, IS_ARRAY, allow_null, pass_by_ref},
+#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, 
sizeof(#name)-1, NULL, 0, type_hint, allow_null, pass_by_ref},
 #define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, 
required_num_args)      \
        static const zend_arg_info name[] = {                                   
                                                                                
                        \
-               { NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, 
return_reference, required_num_args },
+               { NULL, 0, NULL, required_num_args, 0, return_reference, 
pass_rest_by_reference},
 #define ZEND_BEGIN_ARG_INFO(name, pass_rest_by_reference)      \
        ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, ZEND_RETURN_VALUE, 
-1)
 #define ZEND_END_ARG_INFO()            };
@@ -173,7 +173,6 @@
                        class_container.name = zend_strndup(cl_name, _len);     
\
                }                                                               
                                                \
                class_container.name_length = _len;                             
                \
-               class_container.builtin_functions = functions;                  
\
                class_container.constructor = NULL;                             
                \
                class_container.destructor = NULL;                              
                \
                class_container.clone = NULL;                                   
                \
@@ -202,7 +201,8 @@
                class_container.interfaces = NULL;                              
                \
                class_container.get_iterator = NULL;                            
        \
                class_container.iterator_funcs.funcs = NULL;                    
\
-               class_container.module = NULL;                                  
                \
+               class_container.info.internal.module = NULL;                    
\
+               class_container.info.internal.builtin_functions = functions;    
\
        }
 
 #define INIT_OVERLOADED_CLASS_ENTRY(class_container, class_name, functions, 
handle_fcall, handle_propget, handle_propset) \
Index: Zend/zend_globals.h
===================================================================
--- Zend/zend_globals.h (revision 303306)
+++ Zend/zend_globals.h (working copy)
@@ -139,8 +139,8 @@
        zend_bool  in_namespace;
        zend_bool  has_bracketed_namespaces;
 
-       HashTable *labels;
-       zend_stack labels_stack;
+       zend_compiler_context context;
+       zend_stack context_stack;
 
        /* interned strings */
        char *interned_strings_start;
@@ -265,6 +265,8 @@
 
        zend_bool active; 
 
+       zend_op *start_op;
+
        void *saved_fpu_cw_ptr;
 #if XPFPA_HAVE_CW
        XPFPA_CW_DATATYPE saved_fpu_cw;
Index: Zend/zend_execute_API.c
===================================================================
--- Zend/zend_execute_API.c     (revision 303306)
+++ Zend/zend_execute_API.c     (working copy)
@@ -194,6 +194,7 @@
        EG(active_op_array) = NULL;
 
        EG(active) = 1;
+       EG(start_op) = NULL;
 }
 /* }}} */
 
@@ -1256,7 +1257,7 @@
        int orig_interactive;
 
        if (!(CG(active_op_array)->fn_flags & ZEND_ACC_INTERACTIVE)
-               || CG(active_op_array)->backpatch_count>0
+               || CG(context).backpatch_count>0
                || CG(active_op_array)->function_name
                || CG(active_op_array)->type!=ZEND_USER_FUNCTION) {
                return;
@@ -1268,11 +1269,11 @@
        ret_opline->op1.constant = zend_add_literal(CG(active_op_array), 
&EG(uninitialized_zval));
        SET_UNUSED(ret_opline->op2);
 
-       if (!CG(active_op_array)->start_op) {
-               CG(active_op_array)->start_op = CG(active_op_array)->opcodes;
+       if (!EG(start_op)) {
+               EG(start_op) = CG(active_op_array)->opcodes;
        }
 
-       opline=CG(active_op_array)->start_op;
+       opline=EG(start_op);
        end=CG(active_op_array)->opcodes+CG(active_op_array)->last;
 
        while (opline<end) {
@@ -1317,7 +1318,7 @@
        }
 
        CG(active_op_array)->last -= 1; /* get rid of that ZEND_RETURN */
-       CG(active_op_array)->start_op = 
CG(active_op_array)->opcodes+CG(active_op_array)->last;
+       EG(start_op) = CG(active_op_array)->opcodes+CG(active_op_array)->last;
 }
 /* }}} */
 
Index: Zend/zend_opcode.c
===================================================================
--- Zend/zend_opcode.c  (revision 303306)
+++ Zend/zend_opcode.c  (working copy)
@@ -43,31 +43,28 @@
        }
 }
 
-static void op_array_alloc_ops(zend_op_array *op_array)
+static void op_array_alloc_ops(zend_op_array *op_array, zend_uint size)
 {
-       op_array->opcodes = erealloc(op_array->opcodes, 
(op_array->size)*sizeof(zend_op));
+       op_array->opcodes = erealloc(op_array->opcodes, size * sizeof(zend_op));
 }
 
 void init_op_array(zend_op_array *op_array, zend_uchar type, int 
initial_ops_size TSRMLS_DC)
 {
        op_array->type = type;
 
-       op_array->backpatch_count = 0;
        if (CG(interactive)) {
                /* We must avoid a realloc() on the op_array in interactive 
mode, since pointers to constants
                 * will become invalid
                 */
-               initial_ops_size = 8192;
+               initial_ops_size = INITIAL_INTERACTIVE_OP_ARRAY_SIZE;
        }
 
        op_array->refcount = (zend_uint *) emalloc(sizeof(zend_uint));
        *op_array->refcount = 1;
-       op_array->size = initial_ops_size;
        op_array->last = 0;
        op_array->opcodes = NULL;
-       op_array_alloc_ops(op_array);
+       op_array_alloc_ops(op_array, initial_ops_size);
 
-       op_array->size_var = 0;
        op_array->last_var = 0;
        op_array->vars = NULL;
 
@@ -87,23 +84,16 @@
        op_array->brk_cont_array = NULL;
        op_array->try_catch_array = NULL;
        op_array->last_brk_cont = 0;
-       op_array->current_brk_cont = -1;
 
        op_array->static_variables = NULL;
        op_array->last_try_catch = 0;
 
-       op_array->return_reference = 0;
-       op_array->done_pass_two = 0;
-
        op_array->this_var = -1;
 
-       op_array->start_op = NULL;
-
        op_array->fn_flags = CG(interactive)?ZEND_ACC_INTERACTIVE:0;
 
        op_array->early_binding = -1;
 
-       op_array->size_literal = 0;
        op_array->last_literal = 0;
        op_array->literals = NULL;
 
@@ -309,8 +299,8 @@
                        if (ce->num_interfaces > 0 && ce->interfaces) {
                                efree(ce->interfaces);
                        }
-                       if (ce->doc_comment) {
-                               efree(ce->doc_comment);
+                       if (ce->info.user.doc_comment) {
+                               efree(ce->info.user.doc_comment);
                        }
                        
                        _destroy_zend_class_traits_info(ce);
@@ -345,9 +335,6 @@
                        if (ce->num_interfaces > 0) {
                                free(ce->interfaces);
                        }
-                       if (ce->doc_comment) {
-                               free(ce->doc_comment);
-                       }
                        free(ce);
                        break;
        }
@@ -410,7 +397,7 @@
        if (op_array->try_catch_array) {
                efree(op_array->try_catch_array);
        }
-       if (op_array->done_pass_two) {
+       if (op_array->fn_flags & ZEND_ACC_DONE_PASS_TWO) {
                zend_llist_apply_with_argument(&zend_extensions, 
(llist_apply_with_arg_func_t) zend_extension_op_array_dtor_handler, op_array 
TSRMLS_CC);
        }
        if (op_array->arg_info) {
@@ -436,15 +423,15 @@
        zend_uint next_op_num = op_array->last++;
        zend_op *next_op;
 
-       if (next_op_num >= op_array->size) {
+       if (next_op_num >= CG(context).opcodes_size) {
                if (op_array->fn_flags & ZEND_ACC_INTERACTIVE) {
                        /* we messed up */
                        zend_printf("Ran out of opcode space!\n"
                                                "You should probably consider 
writing this huge script into a file!\n");
                        zend_bailout();
                }
-               op_array->size *= 4;
-               op_array_alloc_ops(op_array);
+               CG(context).opcodes_size *= 4;
+               op_array_alloc_ops(op_array, CG(context).opcodes_size);
        }
        
        next_op = &(op_array->opcodes[next_op_num]);
@@ -510,13 +497,17 @@
                zend_llist_apply_with_argument(&zend_extensions, 
(llist_apply_with_arg_func_t) zend_extension_op_array_handler, op_array 
TSRMLS_CC);
        }
 
-       if (!(op_array->fn_flags & ZEND_ACC_INTERACTIVE) && op_array->size != 
op_array->last) {
+       if (!(op_array->fn_flags & ZEND_ACC_INTERACTIVE) && 
CG(context).vars_size != op_array->last_var) {
+               op_array->vars = (zend_compiled_variable *) 
erealloc(op_array->vars, sizeof(zend_compiled_variable)*op_array->last_var);
+               CG(context).vars_size = op_array->last_var;
+       }
+       if (!(op_array->fn_flags & ZEND_ACC_INTERACTIVE) && 
CG(context).opcodes_size != op_array->last) {
                op_array->opcodes = (zend_op *) erealloc(op_array->opcodes, 
sizeof(zend_op)*op_array->last);
-               op_array->size = op_array->last;
+               CG(context).opcodes_size = op_array->last;
        }
-       if (!(op_array->fn_flags & ZEND_ACC_INTERACTIVE) && 
op_array->size_literal != op_array->last_literal) {
+       if (!(op_array->fn_flags & ZEND_ACC_INTERACTIVE) && 
CG(context).literals_size != op_array->last_literal) {
                op_array->literals = 
(zend_literal*)erealloc(op_array->literals, sizeof(zend_literal) * 
op_array->last_literal);
-               op_array->size_literal = op_array->last_literal;
+               CG(context).literals_size = op_array->last_literal;
        }
 
        opline = op_array->opcodes;
@@ -549,7 +540,7 @@
                opline++;
        }
 
-       op_array->done_pass_two = 1;
+       op_array->fn_flags |= ZEND_ACC_DONE_PASS_TWO;
        return 0;
 }
 

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to