Index: zend_compile.c =================================================================== RCS file: /repository/ZendEngine2/zend_compile.c,v retrieving revision 1.819 diff -u -r1.819 zend_compile.c --- zend_compile.c 24 Apr 2008 16:15:33 -0000 1.819 +++ zend_compile.c 25 Apr 2008 09:05:00 -0000 @@ -166,6 +166,8 @@ CG(labels) = NULL; CG(current_namespace) = NULL; CG(current_import) = NULL; + zend_stack_init(&CG(array_stack)); + CG(array_size) = 0; } /* }}} */ @@ -205,6 +207,7 @@ zend_hash_destroy(&CG(filenames_table)); zend_llist_destroy(&CG(open_files)); zend_stack_destroy(&CG(labels_stack)); + zend_stack_destroy(&CG(array_stack)); } /* }}} */ @@ -4054,6 +4057,14 @@ opline->result.op_type = IS_TMP_VAR; *result = opline->result; if (expr) { + zend_array_size_info size_info; + + size_info.opline_num = get_next_op_number(CG(active_op_array)) - 1; + size_info.prev_size = CG(array_size); + zend_stack_push(&CG(array_stack), (void *) &size_info, sizeof(zend_array_size_info)); + + CG(array_size) = 1; + opline->op1 = *expr; if (offset) { opline->op2 = *offset; @@ -4072,6 +4083,8 @@ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); + CG(array_size)++; + opline->opcode = ZEND_ADD_ARRAY_ELEMENT; opline->result = *result; opline->op1 = *expr; @@ -4084,6 +4097,26 @@ } /* }}} */ +void zend_do_end_array(TSRMLS_D) /* {{{ */ +{ + zend_array_size_info *size_info; + + zend_stack_top(&CG(array_stack), (void **) &size_info); + + /* If size is odd, make it even so updating INIT_ARRAY's extended_value + doesn't set the first bit (is_ref flag). This won't cause the array + to be made larger since the HashTable size is a power of 2 anyway */ + if (CG(array_size) & 1) { + CG(array_size)++; + } + + CG(active_op_array)->opcodes[size_info->opline_num].extended_value |= CG(array_size); + CG(array_size) = size_info->prev_size; + + zend_stack_del_top(&CG(array_stack)); +} +/* }}} */ + void zend_do_add_static_array_element(znode *result, znode *offset, znode *expr) /* {{{ */ { zval *element; Index: zend_compile.h =================================================================== RCS file: /repository/ZendEngine2/zend_compile.h,v retrieving revision 1.378 diff -u -r1.378 zend_compile.h --- zend_compile.h 26 Mar 2008 14:23:01 -0000 1.378 +++ zend_compile.h 25 Apr 2008 08:28:40 -0000 @@ -100,6 +100,11 @@ zend_uint opline_num; } zend_label; +typedef struct _zend_array_size_info { + zend_uint opline_num; + zend_uint prev_size; +} zend_array_size_info; + typedef struct _zend_try_catch_element { zend_uint try_op; zend_uint catch_op; /* ketchup! */ @@ -484,6 +489,7 @@ void zend_do_init_array(znode *result, znode *expr, znode *offset, zend_bool is_ref TSRMLS_DC); void zend_do_add_array_element(znode *result, znode *expr, znode *offset, zend_bool is_ref TSRMLS_DC); +void zend_do_end_array(TSRMLS_D); void zend_do_add_static_array_element(znode *result, znode *offset, znode *expr); void zend_do_list_init(TSRMLS_D); void zend_do_list_end(znode *result, znode *expr TSRMLS_DC); Index: zend_globals.h =================================================================== RCS file: /repository/ZendEngine2/zend_globals.h,v retrieving revision 1.179 diff -u -r1.179 zend_globals.h --- zend_globals.h 9 Apr 2008 21:07:45 -0000 1.179 +++ zend_globals.h 25 Apr 2008 08:26:00 -0000 @@ -140,6 +140,9 @@ zval *current_namespace; HashTable *current_import; + zend_uint array_size; + zend_stack array_stack; + #ifdef ZTS HashTable **static_members; int last_static_member; Index: zend_language_parser.y =================================================================== RCS file: /repository/ZendEngine2/zend_language_parser.y,v retrieving revision 1.204 diff -u -r1.204 zend_language_parser.y --- zend_language_parser.y 23 Feb 2008 17:03:51 -0000 1.204 +++ zend_language_parser.y 25 Apr 2008 08:30:10 -0000 @@ -902,7 +902,7 @@ array_pair_list: /* empty */ { zend_do_init_array(&$$, NULL, NULL, 0 TSRMLS_CC); } - | non_empty_array_pair_list possible_comma { $$ = $1; } + | non_empty_array_pair_list possible_comma { zend_do_end_array(TSRMLS_C); $$ = $1; } ; non_empty_array_pair_list: Index: zend_vm_def.h =================================================================== RCS file: /repository/ZendEngine2/zend_vm_def.h,v retrieving revision 1.225 diff -u -r1.225 zend_vm_def.h --- zend_vm_def.h 24 Apr 2008 15:46:28 -0000 1.225 +++ zend_vm_def.h 25 Apr 2008 08:35:00 -0000 @@ -2936,7 +2936,7 @@ #if !defined(ZEND_VM_SPEC) || OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV zval **expr_ptr_ptr = NULL; - if (opline->extended_value) { + if (opline->extended_value & 1) { expr_ptr_ptr=GET_OP1_ZVAL_PTR_PTR(BP_VAR_W); expr_ptr = *expr_ptr_ptr; } else { @@ -2954,7 +2954,7 @@ expr_ptr = new_expr; } else { #if !defined(ZEND_VM_SPEC) || OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV - if (opline->extended_value) { + if (opline->extended_value & 1) { SEPARATE_ZVAL_TO_MAKE_IS_REF(expr_ptr_ptr); expr_ptr = *expr_ptr_ptr; Z_ADDREF_P(expr_ptr); @@ -2997,7 +2997,7 @@ } else { zend_hash_next_index_insert(Z_ARRVAL_P(array_ptr), &expr_ptr, sizeof(zval *), NULL); } - if (opline->extended_value) { + if (opline->extended_value & 1) { FREE_OP1_VAR_PTR(); } else { FREE_OP1_IF_VAR(); @@ -3009,7 +3009,7 @@ { zend_op *opline = EX(opline); - array_init(&EX_T(opline->result.u.var).tmp_var); + array_init_size(&EX_T(opline->result.u.var).tmp_var, opline->extended_value & ~1); if (OP1_TYPE == IS_UNUSED) { ZEND_VM_NEXT_OPCODE(); #if !defined(ZEND_VM_SPEC) || OP1_TYPE != IS_UNUSED