Re: [PATCH] Lazy symbol table initialization
| From: | Marcus Boerger | Date: | Sun, 27 Apr 2008 20:14:18 +0000 |
| Subject: | Re: [PATCH] Lazy symbol table initialization | ||
| References: | 1 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-37262@lists.php.net to get a copy of this message | ||
Hello Dmitry,
/me does a little speed dance! Awesome work :-)
marcus
Friday, April 25, 2008, 3:29:21 PM, you wrote:
> Index: Zend/zend.c
> ===================================================================
> RCS file: /repository/ZendEngine2/zend.c,v
> retrieving revision 1.308.2.12.2.35.2.17
> diff -u -p -d -r1.308.2.12.2.35.2.17 zend.c
> --- Zend/zend.c 17 Apr 2008 10:21:38 -0000 1.308.2.12.2.35.2.17
> +++ Zend/zend.c 25 Apr 2008 13:02:24 -0000
> @@ -1071,6 +1071,9 @@ ZEND_API void zend_error(int type, const
> Z_LVAL_P(z_error_lineno) = error_lineno;
> Z_TYPE_P(z_error_lineno) = IS_LONG;
>
> + if (!EG(active_symbol_table)) {
> + zend_rebuild_symbol_table(TSRMLS_C);
> + }
> Z_ARRVAL_P(z_context) = EG(active_symbol_table);
> Z_TYPE_P(z_context) = IS_ARRAY;
> zval_copy_ctor(z_context);
> Index: Zend/zend_API.h
> ===================================================================
> RCS file: /repository/ZendEngine2/zend_API.h,v
> retrieving revision 1.207.2.8.2.8.2.9
> diff -u -p -d -r1.207.2.8.2.8.2.9 zend_API.h
> --- Zend/zend_API.h 10 Mar 2008 22:02:41 -0000 1.207.2.8.2.8.2.9
> +++ Zend/zend_API.h 25 Apr 2008 13:02:24 -0000
> @@ -464,6 +464,8 @@ ZEND_API int zend_delete_global_variable
>
> ZEND_API void zend_reset_all_cv(HashTable *symbol_table TSRMLS_DC);
>
> +ZEND_API void zend_rebuild_symbol_table(TSRMLS_D);
> +
> #define add_method(arg, key, method) add_assoc_function((arg), (key), (method))
>
> ZEND_API ZEND_FUNCTION(display_disabled_function);
> Index: Zend/zend_builtin_functions.c
> ===================================================================
> RCS file: /repository/ZendEngine2/zend_builtin_functions.c,v
> retrieving revision 1.277.2.12.2.25.2.14
> diff -u -p -d -r1.277.2.12.2.25.2.14 zend_builtin_functions.c
> --- Zend/zend_builtin_functions.c 10 Mar 2008 22:02:41 -0000 1.277.2.12.2.25.2.14
> +++ Zend/zend_builtin_functions.c 25 Apr 2008 13:02:24 -0000
> @@ -1485,6 +1485,10 @@ ZEND_FUNCTION(get_defined_vars)
>
> array_init(return_value);
>
> + if (!EG(active_symbol_table)) {
> + zend_rebuild_symbol_table();
> + }
> +
> zend_hash_copy(Z_ARRVAL_P(return_value), EG(active_symbol_table),
> (copy_ctor_func_t)zval_add_ref, &tmp, sizeof(zval
> *));
> }
> Index: Zend/zend_compile.c
> ===================================================================
> RCS file: /repository/ZendEngine2/zend_compile.c,v
> retrieving revision 1.647.2.27.2.41.2.59
> diff -u -p -d -r1.647.2.27.2.41.2.59 zend_compile.c
> --- Zend/zend_compile.c 10 Apr 2008 19:19:03 -0000 1.647.2.27.2.41.2.59
> +++ Zend/zend_compile.c 25 Apr 2008 13:02:25 -0000
> @@ -2178,7 +2178,9 @@ void zend_do_begin_catch(znode *try_toke
> opline->opcode = ZEND_CATCH;
> opline->op1 = catch_class;
> /* SET_UNUSED(opline->op1); */ /* FIXME: Define IS_CLASS or something like that */
> - opline->op2 = *catch_var;
> + opline->op2.op_type = IS_CV;
> + opline->op2.u.var = lookup_cv(CG(active_op_array),
> catch_var->u.constant.value.str.val, catch_var->u.constant.value.str.len);
> + opline->op2.u.EA.type = 0;
> opline->op1.u.EA.type = 0; /* 1 means it's the last catch in the block */
>
> try_token->u.opline_num = catch_op_number;
> @@ -2529,7 +2531,7 @@ static zend_bool do_inherit_property_acc
>
> if
> (zend_hash_quick_find(&parent_ce->default_properties, parent_info->name,
> parent_info->name_length+1, parent_info->h, (void **) &pvalue) == SUCCESS)
> Z_ADDREF_PP(pvalue);
> -
> zend_hash_del(&ce->default_properties, child_info->name,
> child_info->name_length+1);
> +
> zend_hash_quick_del(&ce->default_properties, child_info->name,
> child_info->name_length+1, parent_info->h);
>
> zend_hash_quick_update(&ce->default_properties, parent_info->name,
> parent_info->name_length+1, parent_info->h, pvalue, sizeof(zval *), NULL);
> }
> }
> @@ -4124,10 +4126,7 @@ void zend_do_unset(znode *variable TSRML
> if (variable->op_type == IS_CV) {
> zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
> opline->opcode = ZEND_UNSET_VAR;
> - opline->op1.op_type = IS_CONST;
> - opline->op1.u.constant.type = IS_STRING;
> - opline->op1.u.constant.value.str.len =
> CG(active_op_array)->vars[variable->u.var].name_len;
> - opline->op1.u.constant.value.str.val =
> estrdup(CG(active_op_array)->vars[variable->u.var].name);
> + opline->op1 = *variable;
> SET_UNUSED(opline->op2);
> opline->op2.u.EA.type = ZEND_FETCH_LOCAL;
> SET_UNUSED(opline->result);
> @@ -4161,10 +4160,7 @@ void zend_do_isset_or_isempty(int type,
> if (variable->op_type == IS_CV) {
> last_op = get_next_op(CG(active_op_array) TSRMLS_CC);
> last_op->opcode = ZEND_ISSET_ISEMPTY_VAR;
> - last_op->op1.op_type = IS_CONST;
> - last_op->op1.u.constant.type = IS_STRING;
> - last_op->op1.u.constant.value.str.len =
> CG(active_op_array)->vars[variable->u.var].name_len;
> - last_op->op1.u.constant.value.str.val =
> estrdup(CG(active_op_array)->vars[variable->u.var].name);
> + last_op->op1 = *variable;
> SET_UNUSED(last_op->op2);
> last_op->op2.u.EA.type = ZEND_FETCH_LOCAL;
> last_op->result.u.var =
> get_temporary_variable(CG(active_op_array));
> Index: Zend/zend_execute.c
> ===================================================================
> RCS file: /repository/ZendEngine2/zend_execute.c,v
> retrieving revision 1.716.2.12.2.24.2.25
> diff -u -p -d -r1.716.2.12.2.24.2.25 zend_execute.c
> --- Zend/zend_execute.c 24 Apr 2008 15:45:46 -0000 1.716.2.12.2.24.2.25
> +++ Zend/zend_execute.c 25 Apr 2008 13:02:25 -0000
> @@ -169,14 +169,6 @@ ZEND_API zval** zend_get_compiled_variab
> return execute_data_ptr->CVs[var];
> }
>
> -static inline void zend_get_cv_address(zend_compiled_variable *cv, zval ***ptr, temp_variable
> *Ts TSRMLS_DC)
> -{
> - zval *new_zval = &EG(uninitialized_zval);
> -
> - Z_ADDREF_P(new_zval);
> - zend_hash_quick_update(EG(active_symbol_table), cv->name,
> cv->name_len+1, cv->hash_value, &new_zval, sizeof(zval *), (void **)ptr);
> -}
> -
> static inline zval *_get_zval_ptr_tmp(znode *node, temp_variable *Ts, zend_free_op
> *should_free TSRMLS_DC)
> {
> return should_free->var = &T(node->u.var).tmp_var;
> @@ -220,7 +212,8 @@ static inline zval *_get_zval_ptr_cv(zno
>
> if (!*ptr) {
> zend_compiled_variable *cv = &CV_DEF_OF(node->u.var);
> - if (zend_hash_quick_find(EG(active_symbol_table),
> cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
> + if (!EG(active_symbol_table) ||
> + zend_hash_quick_find(EG(active_symbol_table),
> cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
> switch (type) {
> case BP_VAR_R:
> case BP_VAR_UNSET:
> @@ -233,7 +226,13 @@ static inline zval *_get_zval_ptr_cv(zno
> zend_error(E_NOTICE, "Undefined variable:
> %s", cv->name);
> /* break missing intentionally */
> case BP_VAR_W:
> - zend_get_cv_address(cv, ptr, Ts TSRMLS_CC);
> + Z_ADDREF(EG(uninitialized_zval));
> + if (!EG(active_symbol_table)) {
> + *ptr =
> (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + node->u.var);
> + **ptr = &EG(uninitialized_zval);
> + } else {
> +
> zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1,
> cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr);
> + }
> break;
> }
> }
> @@ -288,7 +287,9 @@ static inline zval **_get_zval_ptr_ptr_c
>
> if (!*ptr) {
> zend_compiled_variable *cv = &CV_DEF_OF(node->u.var);
> - if (zend_hash_quick_find(EG(active_symbol_table),
> cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
> +
> + if (!EG(active_symbol_table) ||
> + zend_hash_quick_find(EG(active_symbol_table),
> cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
> switch (type) {
> case BP_VAR_R:
> case BP_VAR_UNSET:
> @@ -301,7 +302,13 @@ static inline zval **_get_zval_ptr_ptr_c
> zend_error(E_NOTICE, "Undefined variable:
> %s", cv->name);
> /* break missing intentionally */
> case BP_VAR_W:
> - zend_get_cv_address(cv, ptr, Ts TSRMLS_CC);
> + Z_ADDREF(EG(uninitialized_zval));
> + if (!EG(active_symbol_table)) {
> + *ptr =
> (zval**)EG(current_execute_data)->CVs + (EG(active_op_array)->last_var + node->u.var);
> + **ptr = &EG(uninitialized_zval);
> + } else {
> +
> zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1,
> cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr);
> + }
> break;
> }
> }
> @@ -762,6 +769,9 @@ static inline HashTable *zend_get_target
> {
> switch (opline->op2.u.EA.type) {
> case ZEND_FETCH_LOCAL:
> + if (!EG(active_symbol_table)) {
> + zend_rebuild_symbol_table(TSRMLS_C);
> + }
> return EG(active_symbol_table);
> break;
> case ZEND_FETCH_GLOBAL:
> @@ -1298,11 +1308,21 @@ ZEND_API void execute_internal(zend_exec
> #define ZEND_VM_INC_OPCODE() \
> EX(opline)++
>
> -#define ZEND_VM_EXIT_FROM_EXECUTE_LOOP() \
> - EG(in_execution) = EX(original_in_execution); \
> - EG(current_execute_data) = EX(prev_execute_data); \
> - EG(opline_ptr) = NULL; \
> - zend_vm_stack_free(execute_data TSRMLS_CC);
> +#define ZEND_VM_EXIT_FROM_EXECUTE_LOOP() do { \
> + EG(in_execution) = EX(original_in_execution); \
> + EG(current_execute_data) = EX(prev_execute_data); \
> + EG(opline_ptr) = NULL; \
> + if (!EG(active_symbol_table)) { \
> + int n = EX(op_array)->last_var; \
> + while (n > 0) { \
> + --n; \
> + if (EX(CVs)[n]) { \
> + zval_ptr_dtor(EX(CVs)[n]); \
> + } \
> + } \
> + } \
> + zend_vm_stack_free(execute_data TSRMLS_CC); \
> + } while (0);
>
> #define ZEND_VM_RETURN_FROM_EXECUTE_LOOP() \
> ZEND_VM_EXIT_FROM_EXECUTE_LOOP() \
> Index: Zend/zend_execute_API.c
> ===================================================================
> RCS file: /repository/ZendEngine2/zend_execute_API.c,v
> retrieving revision 1.331.2.20.2.24.2.35
> diff -u -p -d -r1.331.2.20.2.24.2.35 zend_execute_API.c
> --- Zend/zend_execute_API.c 11 Apr 2008 09:43:27 -0000 1.331.2.20.2.24.2.35
> +++ Zend/zend_execute_API.c 25 Apr 2008 13:02:25 -0000
> @@ -1777,12 +1777,49 @@ ZEND_API int zend_delete_global_variable
> }
> }
> }
> - return zend_hash_del(&EG(symbol_table), name, name_len + 1);
> + return zend_hash_quick_del(&EG(symbol_table), name, name_len + 1,
> hash_value);
> }
> return FAILURE;
> }
> /* }}} */
>
> +ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */
> +{
> + zend_uint i;
> +
> + if (!EG(active_symbol_table)) {
> + if (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
> + /*printf("Cache hit! Reusing %x\n",
> symtable_cache[symtable_cache_ptr]);*/
> + EG(active_symbol_table) = *(EG(symtable_cache_ptr)--);
> + } else {
> + ALLOC_HASHTABLE(EG(active_symbol_table));
> + zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0);
> + /*printf("Cache miss! Initialized %x\n",
> EG(active_symbol_table));*/
> + }
> + if (EG(current_execute_data) &&
> EG(current_execute_data)->op_array) {
> + EG(current_execute_data)->symbol_table = EG(active_symbol_table);
> + if (EG(current_execute_data)->op_array->uses_this &&
> EG(This)) {
> + Z_ADDREF_P(EG(This)); /* For $this pointer */
> + if
> (zend_hash_add(EG(active_symbol_table), "this", sizeof("this"),
> &EG(This), sizeof(zval *), NULL)==FAILURE) {
> + Z_DELREF_P(EG(This));
> + }
> + }
> + for (i = 0; i <
> EG(current_execute_data)->op_array->last_var; i++) {
> + if (EG(current_execute_data)->CVs[i]) {
> +
> zend_hash_quick_update(EG(active_symbol_table),
> +
> EG(current_execute_data)->op_array->vars[i].name,
> +
> EG(current_execute_data)->op_array->vars[i].name_len + 1,
> +
> EG(current_execute_data)->op_array->vars[i].hash_value,
> +
> (void**)EG(current_execute_data)->CVs[i],
> + sizeof(zval*),
> +
> (void**)&EG(current_execute_data)->CVs[i]);
> + }
> + }
> + }
> + }
> +}
> +/* }}} */
> +
> /*
> * Local variables:
> * tab-width: 4
> Index: Zend/zend_hash.h
> ===================================================================
> RCS file: /repository/ZendEngine2/zend_hash.h,v
> retrieving revision 1.78.2.2.2.2.2.3
> diff -u -p -d -r1.78.2.2.2.2.2.3 zend_hash.h
> --- Zend/zend_hash.h 15 Jan 2008 09:36:05 -0000 1.78.2.2.2.2.2.3
> +++ Zend/zend_hash.h 25 Apr 2008 13:02:25 -0000
> @@ -35,6 +35,7 @@
>
> #define HASH_DEL_KEY 0
> #define HASH_DEL_INDEX 1
> +#define HASH_DEL_KEY_QUICK 2
>
> typedef ulong (*hash_func_t)(const char *arKey, uint nKeyLength);
> typedef int (*compare_func_t)(const void *, const void * TSRMLS_DC);
> @@ -147,6 +148,8 @@ ZEND_API void zend_hash_reverse_apply(Ha
> ZEND_API int zend_hash_del_key_or_index(HashTable *ht, const char
> *arKey, uint nKeyLength, ulong h, int flag);
> #define zend_hash_del(ht, arKey, nKeyLength) \
> zend_hash_del_key_or_index(ht, arKey, nKeyLength, 0, HASH_DEL_KEY)
> +#define zend_hash_quick_del(ht, arKey, nKeyLength, h) \
> + zend_hash_del_key_or_index(ht, arKey, nKeyLength, h, HASH_DEL_KEY_QUICK)
> #define zend_hash_index_del(ht, h) \
> zend_hash_del_key_or_index(ht, NULL, 0, h, HASH_DEL_INDEX)
>
> Index: Zend/zend_object_handlers.c
> ===================================================================
> RCS file: /repository/ZendEngine2/zend_object_handlers.c,v
> retrieving revision 1.135.2.6.2.22.2.13
> diff -u -p -d -r1.135.2.6.2.22.2.13 zend_object_handlers.c
> --- Zend/zend_object_handlers.c 17 Mar 2008 14:54:42 -0000 1.135.2.6.2.22.2.13
> +++ Zend/zend_object_handlers.c 25 Apr 2008 13:02:25 -0000
> @@ -612,7 +612,7 @@ static void zend_std_unset_property(zval
>
> property_info = zend_get_property_info(zobj->ce, member,
> (zobj->ce->__unset != NULL) TSRMLS_CC);
>
> - if (!property_info || zend_hash_del(zobj->properties,
> property_info->name, property_info->name_length+1) == FAILURE) {
> + if (!property_info || zend_hash_quick_del(zobj->properties,
> property_info->name, property_info->name_length+1, property_info->h) == FAILURE) {
> zend_guard *guard;
>
> if (zobj->ce->__unset &&
> Index: Zend/zend_vm_def.h
> ===================================================================
> RCS file: /repository/ZendEngine2/zend_vm_def.h,v
> retrieving revision 1.59.2.29.2.48.2.49
> diff -u -p -d -r1.59.2.29.2.48.2.49 zend_vm_def.h
> --- Zend/zend_vm_def.h 24 Apr 2008 15:45:46 -0000 1.59.2.29.2.48.2.49
> +++ Zend/zend_vm_def.h 25 Apr 2008 13:02:25 -0000
> @@ -2150,15 +2150,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_help
> } else if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
> zval **original_return_value = EG(return_value_ptr_ptr);
>
> - if (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
> - /*printf("Cache hit! Reusing %x\n",
> symtable_cache[symtable_cache_ptr]);*/
> - EG(active_symbol_table) = *(EG(symtable_cache_ptr)--);
> - } else {
> - ALLOC_HASHTABLE(EG(active_symbol_table));
> - zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0);
> - /*printf("Cache miss! Initialized %x\n",
> EG(active_symbol_table));*/
> - }
> -
> + EG(active_symbol_table) = NULL;
> EG(active_op_array) =
> &EX(function_state).function->op_array;
> EG(return_value_ptr_ptr) = NULL;
> if (RETURN_VALUE_USED(opline)) {
> @@ -2173,14 +2165,16 @@ ZEND_VM_HELPER(zend_do_fcall_common_help
> EG(opline_ptr) = &EX(opline);
> EG(active_op_array) = EX(op_array);
> EG(return_value_ptr_ptr)=original_return_value;
> - if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
> - zend_hash_destroy(EG(active_symbol_table));
> - FREE_HASHTABLE(EG(active_symbol_table));
> - } else {
> - /* clean before putting into the cache, since clean
> - could call dtors, which could use cached hash */
> - zend_hash_clean(EG(active_symbol_table));
> - *(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
> + if (EG(active_symbol_table)) {
> + if
> (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
> + zend_hash_destroy(EG(active_symbol_table));
> + FREE_HASHTABLE(EG(active_symbol_table));
> + } else {
> + /* clean before putting into the cache, since clean
> + could call dtors, which could use cached hash */
> + zend_hash_clean(EG(active_symbol_table));
> + *(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
> + }
> }
> EG(active_symbol_table) = EX(symbol_table);
> } else { /* ZEND_OVERLOADED_FUNCTION */
> @@ -2364,7 +2358,7 @@ ZEND_VM_HANDLER(108, ZEND_THROW, CONST|T
> ZEND_VM_NEXT_OPCODE();
> }
>
> -ZEND_VM_HANDLER(107, ZEND_CATCH, ANY, ANY)
> +ZEND_VM_HANDLER(107, ZEND_CATCH, ANY, CV)
> {
> zend_op *opline = EX(opline);
> zend_class_entry *ce;
> @@ -2386,8 +2380,17 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, ANY, AN
> }
> }
>
> - zend_hash_update(EG(active_symbol_table),
> opline->op2.u.constant.value.str.val,
> - opline->op2.u.constant.value.str.len+1, &EG(exception), sizeof(zval *),
> (void **) NULL);
> + if (!EG(active_symbol_table)) {
> + if (EX(CVs)[opline->op2.u.var]) {
> + zval_ptr_dtor(EX(CVs)[opline->op2.u.var]);
> + }
> + EX(CVs)[opline->op2.u.var] = (zval**)EX(CVs) +
> (EX(op_array)->last_var + opline->op2.u.var);
> + *EX(CVs)[opline->op2.u.var] = EG(exception);
> + } else {
> + zend_compiled_variable *cv = &CV_DEF_OF(opline->op2.u.var);
> + zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1,
> cv->hash_value,
> + &EG(exception), sizeof(zval *), NULL);
> + }
> EG(exception) = NULL;
> ZEND_VM_NEXT_OPCODE();
> }
> @@ -3105,6 +3108,10 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL
> EX(function_state).function = (zend_function *) new_op_array;
> EX(object) = NULL;
>
> + if (!EG(active_symbol_table)) {
> + zend_rebuild_symbol_table(TSRMLS_C);
> + }
> +
> zend_execute(new_op_array TSRMLS_CC);
>
> EX(function_state).function = saved_function;
> @@ -3146,6 +3153,36 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONS
> HashTable *target_symbol_table;
> zend_free_op free_op1;
>
> + if (OP1_TYPE == IS_CV) {
> + if (EG(active_symbol_table)) {
> + zend_execute_data *ex = EX(prev_execute_data);
> + zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.u.var);
> +
> + if (zend_hash_quick_del(EG(active_symbol_table),
> cv->name, cv->name_len+1, cv->hash_value) == SUCCESS) {
> + while (ex && ex->symbol_table ==
> EG(active_symbol_table)) {
> + int i;
> +
> + if (ex->op_array) {
> + for (i = 0; i <
> ex->op_array->last_var; i++) {
> + if
> (ex->op_array->vars[i].hash_value == cv->hash_value &&
> +
> ex->op_array->vars[i].name_len == cv->name_len &&
> +
> !memcmp(ex->op_array->vars[i].name, cv->name, cv->name_len)) {
> + ex->CVs[i] = NULL;
> + break;
> + }
> + }
> + }
> + ex = ex->prev_execute_data;
> + }
> + }
> + EX(CVs)[opline->op1.u.var] = NULL;
> + } else if (EX(CVs)[opline->op1.u.var]) {
> + zval_ptr_dtor(EX(CVs)[opline->op1.u.var]);
> + EX(CVs)[opline->op1.u.var] = NULL;
> + }
> + ZEND_VM_NEXT_OPCODE();
> + }
> +
> varname = GET_OP1_ZVAL_PTR(BP_VAR_R);
>
> if (Z_TYPE_P(varname) != IS_STRING) {
> @@ -3153,17 +3190,18 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONS
> zval_copy_ctor(&tmp);
> convert_to_string(&tmp);
> varname = &tmp;
> - } else if (OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) {
> + } else if (OP1_TYPE == IS_VAR) {
> Z_ADDREF_P(varname);
> }
>
> if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
>
> zend_std_unset_static_property(EX_T(opline->op2.u.var).class_entry,
> Z_STRVAL_P(varname), Z_STRLEN_P(varname) TSRMLS_CC);
> } else {
> + ulong hash_value =
> zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);
> +
> target_symbol_table =
> zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
> - if (zend_hash_del(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1) == SUCCESS) {
> + if (zend_hash_quick_del(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1, hash_value) == SUCCESS) {
> zend_execute_data *ex = EXECUTE_DATA;
> - ulong hash_value =
> zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);
>
> do {
> int i;
> @@ -3185,7 +3223,7 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONS
>
> if (varname == &tmp) {
> zval_dtor(&tmp);
> - } else if (OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) {
> + } else if (OP1_TYPE == IS_VAR) {
> zval_ptr_dtor(&varname);
> }
> FREE_OP1();
> @@ -3619,29 +3657,49 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR,
> ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, ANY)
> {
> zend_op *opline = EX(opline);
> - zend_free_op free_op1;
> - zval tmp, *varname = GET_OP1_ZVAL_PTR(BP_VAR_IS);
> zval **value;
> zend_bool isset = 1;
> - HashTable *target_symbol_table;
>
> - if (Z_TYPE_P(varname) != IS_STRING) {
> - tmp = *varname;
> - zval_copy_ctor(&tmp);
> - convert_to_string(&tmp);
> - varname = &tmp;
> - }
> + if (OP1_TYPE == IS_CV) {
> + if (EX(CVs)[opline->op1.u.var]) {
> + value = EX(CVs)[opline->op1.u.var];
> + } else if (EG(active_symbol_table)) {
> + zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.u.var);
>
> - if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
> - value =
> zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry,
> Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1 TSRMLS_CC);
> - if (!value) {
> + if (zend_hash_quick_find(EG(active_symbol_table),
> cv->name, cv->name_len+1, cv->hash_value, (void **) &value) == FAILURE) {
> + isset = 0;
> + }
> + } else {
> isset = 0;
> }
> } else {
> - target_symbol_table =
> zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
> - if (zend_hash_find(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
> - isset = 0;
> + HashTable *target_symbol_table;
> + zend_free_op free_op1;
> + zval tmp, *varname = GET_OP1_ZVAL_PTR(BP_VAR_IS);
> +
> + if (Z_TYPE_P(varname) != IS_STRING) {
> + tmp = *varname;
> + zval_copy_ctor(&tmp);
> + convert_to_string(&tmp);
> + varname = &tmp;
> + }
> +
> + if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
> + value =
> zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry,
> Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1 TSRMLS_CC);
> + if (!value) {
> + isset = 0;
> + }
> + } else {
> + target_symbol_table =
> zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
> + if (zend_hash_find(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
> + isset = 0;
> + }
> }
> +
> + if (varname == &tmp) {
> + zval_dtor(&tmp);
> + }
> + FREE_OP1();
> }
>
> Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
> @@ -3663,11 +3721,6 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_
> break;
> }
>
> - if (varname == &tmp) {
> - zval_dtor(&tmp);
> - }
> - FREE_OP1();
> -
> ZEND_VM_NEXT_OPCODE();
> }
>
> @@ -4024,10 +4077,8 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTI
> int catched = 0;
> zval restored_error_reporting;
>
> - void **stack_frame = (void**)execute_data +
> - (sizeof(zend_execute_data) +
> - sizeof(zval**) * EX(op_array)->last_var +
> - sizeof(temp_variable) * EX(op_array)->T) / sizeof(void*);
> + void **stack_frame = (void**)EX(Ts) +
> + (sizeof(temp_variable) * EX(op_array)->T) / sizeof(void*);
>
> while (zend_vm_stack_top(TSRMLS_C) != stack_frame) {
> zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
> Index: Zend/zend_vm_execute.h
> ===================================================================
> RCS file: /repository/ZendEngine2/zend_vm_execute.h,v
> retrieving revision 1.62.2.30.2.49.2.48
> diff -u -p -d -r1.62.2.30.2.49.2.48 zend_vm_execute.h
> --- Zend/zend_vm_execute.h 24 Apr 2008 15:45:46 -0000 1.62.2.30.2.49.2.48
> +++ Zend/zend_vm_execute.h 25 Apr 2008 13:02:26 -0000
> @@ -46,12 +46,12 @@ ZEND_API void execute(zend_op_array *op_
> /* Initialize execute_data */
> execute_data = (zend_execute_data *)zend_vm_stack_alloc(
> sizeof(zend_execute_data) +
> - sizeof(zval**) * op_array->last_var +
> + sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2) +
> sizeof(temp_variable) * op_array->T TSRMLS_CC);
>
> EX(CVs) = (zval***)((char*)execute_data + sizeof(zend_execute_data));
> memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
> - EX(Ts) = (temp_variable *)(EX(CVs) + op_array->last_var);
> + EX(Ts) = (temp_variable *)(EX(CVs) + op_array->last_var * (EG(active_symbol_table) ?
> 1 : 2));
> EX(fbc) = NULL;
> EX(called_scope) = NULL;
> EX(object) = NULL;
> @@ -69,7 +69,7 @@ ZEND_API void execute(zend_op_array *op_
> ZEND_VM_SET_OPCODE(op_array->opcodes);
> }
>
> - if (op_array->uses_this && EG(This)) {
> + if (op_array->uses_this && EG(This) && EG(active_symbol_table)) {
> Z_ADDREF_P(EG(This)); /* For $this pointer */
> if (zend_hash_add(EG(active_symbol_table), "this",
> sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) {
> Z_DELREF_P(EG(This));
> @@ -197,15 +197,7 @@ static int zend_do_fcall_common_helper_S
> } else if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
> zval **original_return_value = EG(return_value_ptr_ptr);
>
> - if (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
> - /*printf("Cache hit! Reusing %x\n",
> symtable_cache[symtable_cache_ptr]);*/
> - EG(active_symbol_table) = *(EG(symtable_cache_ptr)--);
> - } else {
> - ALLOC_HASHTABLE(EG(active_symbol_table));
> - zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0);
> - /*printf("Cache miss! Initialized %x\n",
> EG(active_symbol_table));*/
> - }
> -
> + EG(active_symbol_table) = NULL;
> EG(active_op_array) =
> &EX(function_state).function->op_array;
> EG(return_value_ptr_ptr) = NULL;
> if (RETURN_VALUE_USED(opline)) {
> @@ -220,14 +212,16 @@ static int zend_do_fcall_common_helper_S
> EG(opline_ptr) = &EX(opline);
> EG(active_op_array) = EX(op_array);
> EG(return_value_ptr_ptr)=original_return_value;
> - if (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
> - zend_hash_destroy(EG(active_symbol_table));
> - FREE_HASHTABLE(EG(active_symbol_table));
> - } else {
> - /* clean before putting into the cache, since clean
> - could call dtors, which could use cached hash */
> - zend_hash_clean(EG(active_symbol_table));
> - *(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
> + if (EG(active_symbol_table)) {
> + if
> (EG(symtable_cache_ptr)>=EG(symtable_cache_limit)) {
> + zend_hash_destroy(EG(active_symbol_table));
> + FREE_HASHTABLE(EG(active_symbol_table));
> + } else {
> + /* clean before putting into the cache, since clean
> + could call dtors, which could use cached hash */
> + zend_hash_clean(EG(active_symbol_table));
> + *(++EG(symtable_cache_ptr)) = EG(active_symbol_table);
> + }
> }
> EG(active_symbol_table) = EX(symbol_table);
> } else { /* ZEND_OVERLOADED_FUNCTION */
> @@ -296,34 +290,6 @@ static int ZEND_DO_FCALL_BY_NAME_SPEC_HA
> return
> zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
> }
>
> -static int ZEND_CATCH_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
> -{
> - zend_op *opline = EX(opline);
> - zend_class_entry *ce;
> -
> - /* Check whether an exception has been thrown, if not, jump over code */
> - if (EG(exception) == NULL) {
> -
> ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
> - ZEND_VM_CONTINUE(); /* CHECK_ME */
> - }
> - ce = Z_OBJCE_P(EG(exception));
> - if (ce != EX_T(opline->op1.u.var).class_entry) {
> - if (!instanceof_function(ce,
> EX_T(opline->op1.u.var).class_entry TSRMLS_CC)) {
> - if (opline->op1.u.EA.type) {
> - zend_throw_exception_internal(NULL TSRMLS_CC);
> - ZEND_VM_NEXT_OPCODE();
> - }
> -
> ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
> - ZEND_VM_CONTINUE(); /* CHECK_ME */
> - }
> - }
> -
> - zend_hash_update(EG(active_symbol_table),
> opline->op2.u.constant.value.str.val,
> - opline->op2.u.constant.value.str.len+1, &EG(exception), sizeof(zval *),
> (void **) NULL);
> - EG(exception) = NULL;
> - ZEND_VM_NEXT_OPCODE();
> -}
> -
> static int ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
> {
> zend_op *opline = EX(opline);
> @@ -504,10 +470,8 @@ static int ZEND_HANDLE_EXCEPTION_SPEC_HA
> int catched = 0;
> zval restored_error_reporting;
>
> - void **stack_frame = (void**)execute_data +
> - (sizeof(zend_execute_data) +
> - sizeof(zval**) * EX(op_array)->last_var +
> - sizeof(temp_variable) * EX(op_array)->T) / sizeof(void*);
> + void **stack_frame = (void**)EX(Ts) +
> + (sizeof(temp_variable) * EX(op_array)->T) / sizeof(void*);
>
> while (zend_vm_stack_top(TSRMLS_C) != stack_frame) {
> zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C);
> @@ -1076,6 +1040,43 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_
> }
>
>
> +static int ZEND_CATCH_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
> +{
> + zend_op *opline = EX(opline);
> + zend_class_entry *ce;
> +
> + /* Check whether an exception has been thrown, if not, jump over code */
> + if (EG(exception) == NULL) {
> +
> ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
> + ZEND_VM_CONTINUE(); /* CHECK_ME */
> + }
> + ce = Z_OBJCE_P(EG(exception));
> + if (ce != EX_T(opline->op1.u.var).class_entry) {
> + if (!instanceof_function(ce,
> EX_T(opline->op1.u.var).class_entry TSRMLS_CC)) {
> + if (opline->op1.u.EA.type) {
> + zend_throw_exception_internal(NULL TSRMLS_CC);
> + ZEND_VM_NEXT_OPCODE();
> + }
> +
> ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[opline->extended_value]);
> + ZEND_VM_CONTINUE(); /* CHECK_ME */
> + }
> + }
> +
> + if (!EG(active_symbol_table)) {
> + if (EX(CVs)[opline->op2.u.var]) {
> + zval_ptr_dtor(EX(CVs)[opline->op2.u.var]);
> + }
> + EX(CVs)[opline->op2.u.var] = (zval**)EX(CVs) +
> (EX(op_array)->last_var + opline->op2.u.var);
> + *EX(CVs)[opline->op2.u.var] = EG(exception);
> + } else {
> + zend_compiled_variable *cv = &CV_DEF_OF(opline->op2.u.var);
> + zend_hash_quick_update(EG(active_symbol_table), cv->name, cv->name_len+1,
> cv->hash_value,
> + &EG(exception), sizeof(zval *), NULL);
> + }
> + EG(exception) = NULL;
> + ZEND_VM_NEXT_OPCODE();
> +}
> +
> static int ZEND_BRK_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
> {
> zend_op *opline = EX(opline);
> @@ -1727,6 +1728,10 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_CON
> EX(function_state).function = (zend_function *) new_op_array;
> EX(object) = NULL;
>
> + if (!EG(active_symbol_table)) {
> + zend_rebuild_symbol_table(TSRMLS_C);
> + }
> +
> zend_execute(new_op_array TSRMLS_CC);
>
> EX(function_state).function = saved_function;
> @@ -1768,6 +1773,36 @@ static int ZEND_UNSET_VAR_SPEC_CONST_HAN
> HashTable *target_symbol_table;
>
>
> + if (IS_CONST == IS_CV) {
> + if (EG(active_symbol_table)) {
> + zend_execute_data *ex = EX(prev_execute_data);
> + zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.u.var);
> +
> + if (zend_hash_quick_del(EG(active_symbol_table),
> cv->name, cv->name_len+1, cv->hash_value) == SUCCESS) {
> + while (ex && ex->symbol_table ==
> EG(active_symbol_table)) {
> + int i;
> +
> + if (ex->op_array) {
> + for (i = 0; i <
> ex->op_array->last_var; i++) {
> + if
> (ex->op_array->vars[i].hash_value == cv->hash_value &&
> +
> ex->op_array->vars[i].name_len == cv->name_len &&
> +
> !memcmp(ex->op_array->vars[i].name, cv->name, cv->name_len)) {
> + ex->CVs[i] = NULL;
> + break;
> + }
> + }
> + }
> + ex = ex->prev_execute_data;
> + }
> + }
> + EX(CVs)[opline->op1.u.var] = NULL;
> + } else if (EX(CVs)[opline->op1.u.var]) {
> + zval_ptr_dtor(EX(CVs)[opline->op1.u.var]);
> + EX(CVs)[opline->op1.u.var] = NULL;
> + }
> + ZEND_VM_NEXT_OPCODE();
> + }
> +
> varname = &opline->op1.u.constant;
>
> if (Z_TYPE_P(varname) != IS_STRING) {
> @@ -1775,17 +1810,18 @@ static int ZEND_UNSET_VAR_SPEC_CONST_HAN
> zval_copy_ctor(&tmp);
> convert_to_string(&tmp);
> varname = &tmp;
> - } else if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
> + } else if (IS_CONST == IS_VAR) {
> Z_ADDREF_P(varname);
> }
>
> if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
>
> zend_std_unset_static_property(EX_T(opline->op2.u.var).class_entry,
> Z_STRVAL_P(varname), Z_STRLEN_P(varname) TSRMLS_CC);
> } else {
> + ulong hash_value =
> zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);
> +
> target_symbol_table =
> zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
> - if (zend_hash_del(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1) == SUCCESS) {
> + if (zend_hash_quick_del(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1, hash_value) == SUCCESS) {
> zend_execute_data *ex = execute_data;
> - ulong hash_value =
> zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);
>
> do {
> int i;
> @@ -1807,7 +1843,7 @@ static int ZEND_UNSET_VAR_SPEC_CONST_HAN
>
> if (varname == &tmp) {
> zval_dtor(&tmp);
> - } else if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
> + } else if (IS_CONST == IS_VAR) {
> zval_ptr_dtor(&varname);
> }
>
> @@ -1969,29 +2005,49 @@ static int ZEND_FE_RESET_SPEC_CONST_HAND
> static int
> ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
> {
> zend_op *opline = EX(opline);
> -
> - zval tmp, *varname = &opline->op1.u.constant;
> zval **value;
> zend_bool isset = 1;
> - HashTable *target_symbol_table;
>
> - if (Z_TYPE_P(varname) != IS_STRING) {
> - tmp = *varname;
> - zval_copy_ctor(&tmp);
> - convert_to_string(&tmp);
> - varname = &tmp;
> - }
> + if (IS_CONST == IS_CV) {
> + if (EX(CVs)[opline->op1.u.var]) {
> + value = EX(CVs)[opline->op1.u.var];
> + } else if (EG(active_symbol_table)) {
> + zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.u.var);
>
> - if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
> - value =
> zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry,
> Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1 TSRMLS_CC);
> - if (!value) {
> + if (zend_hash_quick_find(EG(active_symbol_table),
> cv->name, cv->name_len+1, cv->hash_value, (void **) &value) == FAILURE) {
> + isset = 0;
> + }
> + } else {
> isset = 0;
> }
> } else {
> - target_symbol_table =
> zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
> - if (zend_hash_find(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
> - isset = 0;
> + HashTable *target_symbol_table;
> +
> + zval tmp, *varname = &opline->op1.u.constant;
> +
> + if (Z_TYPE_P(varname) != IS_STRING) {
> + tmp = *varname;
> + zval_copy_ctor(&tmp);
> + convert_to_string(&tmp);
> + varname = &tmp;
> + }
> +
> + if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
> + value =
> zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry,
> Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1 TSRMLS_CC);
> + if (!value) {
> + isset = 0;
> + }
> + } else {
> + target_symbol_table =
> zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
> + if (zend_hash_find(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
> + isset = 0;
> + }
> + }
> +
> + if (varname == &tmp) {
> + zval_dtor(&tmp);
> }
> +
> }
>
> Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
> @@ -2013,10 +2069,6 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_C
> break;
> }
>
> - if (varname == &tmp) {
> - zval_dtor(&tmp);
> - }
> -
> ZEND_VM_NEXT_OPCODE();
> }
>
> @@ -4896,6 +4948,10 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_TMP
> EX(function_state).function = (zend_function *) new_op_array;
> EX(object) = NULL;
>
> + if (!EG(active_symbol_table)) {
> + zend_rebuild_symbol_table(TSRMLS_C);
> + }
> +
> zend_execute(new_op_array TSRMLS_CC);
>
> EX(function_state).function = saved_function;
> @@ -4937,6 +4993,36 @@ static int ZEND_UNSET_VAR_SPEC_TMP_HANDL
> HashTable *target_symbol_table;
> zend_free_op free_op1;
>
> + if (IS_TMP_VAR == IS_CV) {
> + if (EG(active_symbol_table)) {
> + zend_execute_data *ex = EX(prev_execute_data);
> + zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.u.var);
> +
> + if (zend_hash_quick_del(EG(active_symbol_table),
> cv->name, cv->name_len+1, cv->hash_value) == SUCCESS) {
> + while (ex && ex->symbol_table ==
> EG(active_symbol_table)) {
> + int i;
> +
> + if (ex->op_array) {
> + for (i = 0; i <
> ex->op_array->last_var; i++) {
> + if
> (ex->op_array->vars[i].hash_value == cv->hash_value &&
> +
> ex->op_array->vars[i].name_len == cv->name_len &&
> +
> !memcmp(ex->op_array->vars[i].name, cv->name, cv->name_len)) {
> + ex->CVs[i] = NULL;
> + break;
> + }
> + }
> + }
> + ex = ex->prev_execute_data;
> + }
> + }
> + EX(CVs)[opline->op1.u.var] = NULL;
> + } else if (EX(CVs)[opline->op1.u.var]) {
> + zval_ptr_dtor(EX(CVs)[opline->op1.u.var]);
> + EX(CVs)[opline->op1.u.var] = NULL;
> + }
> + ZEND_VM_NEXT_OPCODE();
> + }
> +
> varname = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
>
> if (Z_TYPE_P(varname) != IS_STRING) {
> @@ -4944,17 +5030,18 @@ static int ZEND_UNSET_VAR_SPEC_TMP_HANDL
> zval_copy_ctor(&tmp);
> convert_to_string(&tmp);
> varname = &tmp;
> - } else if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
> + } else if (IS_TMP_VAR == IS_VAR) {
> Z_ADDREF_P(varname);
> }
>
> if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
>
> zend_std_unset_static_property(EX_T(opline->op2.u.var).class_entry,
> Z_STRVAL_P(varname), Z_STRLEN_P(varname) TSRMLS_CC);
> } else {
> + ulong hash_value =
> zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);
> +
> target_symbol_table =
> zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
> - if (zend_hash_del(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1) == SUCCESS) {
> + if (zend_hash_quick_del(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1, hash_value) == SUCCESS) {
> zend_execute_data *ex = execute_data;
> - ulong hash_value =
> zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);
>
> do {
> int i;
> @@ -4976,7 +5063,7 @@ static int ZEND_UNSET_VAR_SPEC_TMP_HANDL
>
> if (varname == &tmp) {
> zval_dtor(&tmp);
> - } else if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
> + } else if (IS_TMP_VAR == IS_VAR) {
> zval_ptr_dtor(&varname);
> }
> zval_dtor(free_op1.var);
> @@ -5138,29 +5225,49 @@ static int ZEND_FE_RESET_SPEC_TMP_HANDLE
> static int
> ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
> {
> zend_op *opline = EX(opline);
> - zend_free_op free_op1;
> - zval tmp, *varname = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1
> TSRMLS_CC);
> zval **value;
> zend_bool isset = 1;
> - HashTable *target_symbol_table;
>
> - if (Z_TYPE_P(varname) != IS_STRING) {
> - tmp = *varname;
> - zval_copy_ctor(&tmp);
> - convert_to_string(&tmp);
> - varname = &tmp;
> - }
> + if (IS_TMP_VAR == IS_CV) {
> + if (EX(CVs)[opline->op1.u.var]) {
> + value = EX(CVs)[opline->op1.u.var];
> + } else if (EG(active_symbol_table)) {
> + zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.u.var);
>
> - if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
> - value =
> zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry,
> Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1 TSRMLS_CC);
> - if (!value) {
> + if (zend_hash_quick_find(EG(active_symbol_table),
> cv->name, cv->name_len+1, cv->hash_value, (void **) &value) == FAILURE) {
> + isset = 0;
> + }
> + } else {
> isset = 0;
> }
> } else {
> - target_symbol_table =
> zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
> - if (zend_hash_find(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
> - isset = 0;
> + HashTable *target_symbol_table;
> + zend_free_op free_op1;
> + zval tmp, *varname = _get_zval_ptr_tmp(&opline->op1, EX(Ts),
> &free_op1 TSRMLS_CC);
> +
> + if (Z_TYPE_P(varname) != IS_STRING) {
> + tmp = *varname;
> + zval_copy_ctor(&tmp);
> + convert_to_string(&tmp);
> + varname = &tmp;
> + }
> +
> + if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
> + value =
> zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry,
> Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1 TSRMLS_CC);
> + if (!value) {
> + isset = 0;
> + }
> + } else {
> + target_symbol_table =
> zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
> + if (zend_hash_find(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
> + isset = 0;
> + }
> }
> +
> + if (varname == &tmp) {
> + zval_dtor(&tmp);
> + }
> + zval_dtor(free_op1.var);
> }
>
> Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
> @@ -5182,11 +5289,6 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_T
> break;
> }
>
> - if (varname == &tmp) {
> - zval_dtor(&tmp);
> - }
> - zval_dtor(free_op1.var);
> -
> ZEND_VM_NEXT_OPCODE();
> }
>
> @@ -8096,6 +8198,10 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_VAR
> EX(function_state).function = (zend_function *) new_op_array;
> EX(object) = NULL;
>
> + if (!EG(active_symbol_table)) {
> + zend_rebuild_symbol_table(TSRMLS_C);
> + }
> +
> zend_execute(new_op_array TSRMLS_CC);
>
> EX(function_state).function = saved_function;
> @@ -8137,6 +8243,36 @@ static int ZEND_UNSET_VAR_SPEC_VAR_HANDL
> HashTable *target_symbol_table;
> zend_free_op free_op1;
>
> + if (IS_VAR == IS_CV) {
> + if (EG(active_symbol_table)) {
> + zend_execute_data *ex = EX(prev_execute_data);
> + zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.u.var);
> +
> + if (zend_hash_quick_del(EG(active_symbol_table),
> cv->name, cv->name_len+1, cv->hash_value) == SUCCESS) {
> + while (ex && ex->symbol_table ==
> EG(active_symbol_table)) {
> + int i;
> +
> + if (ex->op_array) {
> + for (i = 0; i <
> ex->op_array->last_var; i++) {
> + if
> (ex->op_array->vars[i].hash_value == cv->hash_value &&
> +
> ex->op_array->vars[i].name_len == cv->name_len &&
> +
> !memcmp(ex->op_array->vars[i].name, cv->name, cv->name_len)) {
> + ex->CVs[i] = NULL;
> + break;
> + }
> + }
> + }
> + ex = ex->prev_execute_data;
> + }
> + }
> + EX(CVs)[opline->op1.u.var] = NULL;
> + } else if (EX(CVs)[opline->op1.u.var]) {
> + zval_ptr_dtor(EX(CVs)[opline->op1.u.var]);
> + EX(CVs)[opline->op1.u.var] = NULL;
> + }
> + ZEND_VM_NEXT_OPCODE();
> + }
> +
> varname = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC);
>
> if (Z_TYPE_P(varname) != IS_STRING) {
> @@ -8144,17 +8280,18 @@ static int ZEND_UNSET_VAR_SPEC_VAR_HANDL
> zval_copy_ctor(&tmp);
> convert_to_string(&tmp);
> varname = &tmp;
> - } else if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
> + } else if (IS_VAR == IS_VAR) {
> Z_ADDREF_P(varname);
> }
>
> if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
>
> zend_std_unset_static_property(EX_T(opline->op2.u.var).class_entry,
> Z_STRVAL_P(varname), Z_STRLEN_P(varname) TSRMLS_CC);
> } else {
> + ulong hash_value =
> zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);
> +
> target_symbol_table =
> zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
> - if (zend_hash_del(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1) == SUCCESS) {
> + if (zend_hash_quick_del(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1, hash_value) == SUCCESS) {
> zend_execute_data *ex = execute_data;
> - ulong hash_value =
> zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);
>
> do {
> int i;
> @@ -8176,7 +8313,7 @@ static int ZEND_UNSET_VAR_SPEC_VAR_HANDL
>
> if (varname == &tmp) {
> zval_dtor(&tmp);
> - } else if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
> + } else if (IS_VAR == IS_VAR) {
> zval_ptr_dtor(&varname);
> }
> if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
> @@ -8484,29 +8621,49 @@ static int ZEND_FE_FETCH_SPEC_VAR_HANDLE
> static int
> ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
> {
> zend_op *opline = EX(opline);
> - zend_free_op free_op1;
> - zval tmp, *varname = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1
> TSRMLS_CC);
> zval **value;
> zend_bool isset = 1;
> - HashTable *target_symbol_table;
>
> - if (Z_TYPE_P(varname) != IS_STRING) {
> - tmp = *varname;
> - zval_copy_ctor(&tmp);
> - convert_to_string(&tmp);
> - varname = &tmp;
> - }
> + if (IS_VAR == IS_CV) {
> + if (EX(CVs)[opline->op1.u.var]) {
> + value = EX(CVs)[opline->op1.u.var];
> + } else if (EG(active_symbol_table)) {
> + zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.u.var);
>
> - if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
> - value =
> zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry,
> Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1 TSRMLS_CC);
> - if (!value) {
> + if (zend_hash_quick_find(EG(active_symbol_table),
> cv->name, cv->name_len+1, cv->hash_value, (void **) &value) == FAILURE) {
> + isset = 0;
> + }
> + } else {
> isset = 0;
> }
> } else {
> - target_symbol_table =
> zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
> - if (zend_hash_find(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
> - isset = 0;
> + HashTable *target_symbol_table;
> + zend_free_op free_op1;
> + zval tmp, *varname = _get_zval_ptr_var(&opline->op1, EX(Ts),
> &free_op1 TSRMLS_CC);
> +
> + if (Z_TYPE_P(varname) != IS_STRING) {
> + tmp = *varname;
> + zval_copy_ctor(&tmp);
> + convert_to_string(&tmp);
> + varname = &tmp;
> + }
> +
> + if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
> + value =
> zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry,
> Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1 TSRMLS_CC);
> + if (!value) {
> + isset = 0;
> + }
> + } else {
> + target_symbol_table =
> zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
> + if (zend_hash_find(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
> + isset = 0;
> + }
> + }
> +
> + if (varname == &tmp) {
> + zval_dtor(&tmp);
> }
> + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
> }
>
> Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
> @@ -8528,11 +8685,6 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_V
> break;
> }
>
> - if (varname == &tmp) {
> - zval_dtor(&tmp);
> - }
> - if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
> -
> ZEND_VM_NEXT_OPCODE();
> }
>
> @@ -21760,6 +21912,10 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_CV_
> EX(function_state).function = (zend_function *) new_op_array;
> EX(object) = NULL;
>
> + if (!EG(active_symbol_table)) {
> + zend_rebuild_symbol_table(TSRMLS_C);
> + }
> +
> zend_execute(new_op_array TSRMLS_CC);
>
> EX(function_state).function = saved_function;
> @@ -21801,6 +21957,36 @@ static int ZEND_UNSET_VAR_SPEC_CV_HANDLE
> HashTable *target_symbol_table;
>
>
> + if (IS_CV == IS_CV) {
> + if (EG(active_symbol_table)) {
> + zend_execute_data *ex = EX(prev_execute_data);
> + zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.u.var);
> +
> + if (zend_hash_quick_del(EG(active_symbol_table),
> cv->name, cv->name_len+1, cv->hash_value) == SUCCESS) {
> + while (ex && ex->symbol_table ==
> EG(active_symbol_table)) {
> + int i;
> +
> + if (ex->op_array) {
> + for (i = 0; i <
> ex->op_array->last_var; i++) {
> + if
> (ex->op_array->vars[i].hash_value == cv->hash_value &&
> +
> ex->op_array->vars[i].name_len == cv->name_len &&
> +
> !memcmp(ex->op_array->vars[i].name, cv->name, cv->name_len)) {
> + ex->CVs[i] = NULL;
> + break;
> + }
> + }
> + }
> + ex = ex->prev_execute_data;
> + }
> + }
> + EX(CVs)[opline->op1.u.var] = NULL;
> + } else if (EX(CVs)[opline->op1.u.var]) {
> + zval_ptr_dtor(EX(CVs)[opline->op1.u.var]);
> + EX(CVs)[opline->op1.u.var] = NULL;
> + }
> + ZEND_VM_NEXT_OPCODE();
> + }
> +
> varname = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC);
>
> if (Z_TYPE_P(varname) != IS_STRING) {
> @@ -21808,17 +21994,18 @@ static int ZEND_UNSET_VAR_SPEC_CV_HANDLE
> zval_copy_ctor(&tmp);
> convert_to_string(&tmp);
> varname = &tmp;
> - } else if (IS_CV == IS_CV || IS_CV == IS_VAR) {
> + } else if (IS_CV == IS_VAR) {
> Z_ADDREF_P(varname);
> }
>
> if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
>
> zend_std_unset_static_property(EX_T(opline->op2.u.var).class_entry,
> Z_STRVAL_P(varname), Z_STRLEN_P(varname) TSRMLS_CC);
> } else {
> + ulong hash_value =
> zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);
> +
> target_symbol_table =
> zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
> - if (zend_hash_del(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1) == SUCCESS) {
> + if (zend_hash_quick_del(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1, hash_value) == SUCCESS) {
> zend_execute_data *ex = execute_data;
> - ulong hash_value =
> zend_inline_hash_func(varname->value.str.val, varname->value.str.len+1);
>
> do {
> int i;
> @@ -21840,7 +22027,7 @@ static int ZEND_UNSET_VAR_SPEC_CV_HANDLE
>
> if (varname == &tmp) {
> zval_dtor(&tmp);
> - } else if (IS_CV == IS_CV || IS_CV == IS_VAR) {
> + } else if (IS_CV == IS_VAR) {
> zval_ptr_dtor(&varname);
> }
>
> @@ -22002,29 +22189,49 @@ static int ZEND_FE_RESET_SPEC_CV_HANDLER
> static int ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
> {
> zend_op *opline = EX(opline);
> -
> - zval tmp, *varname = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS
> TSRMLS_CC);
> zval **value;
> zend_bool isset = 1;
> - HashTable *target_symbol_table;
>
> - if (Z_TYPE_P(varname) != IS_STRING) {
> - tmp = *varname;
> - zval_copy_ctor(&tmp);
> - convert_to_string(&tmp);
> - varname = &tmp;
> - }
> + if (IS_CV == IS_CV) {
> + if (EX(CVs)[opline->op1.u.var]) {
> + value = EX(CVs)[opline->op1.u.var];
> + } else if (EG(active_symbol_table)) {
> + zend_compiled_variable *cv = &CV_DEF_OF(opline->op1.u.var);
>
> - if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
> - value =
> zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry,
> Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1 TSRMLS_CC);
> - if (!value) {
> + if (zend_hash_quick_find(EG(active_symbol_table),
> cv->name, cv->name_len+1, cv->hash_value, (void **) &value) == FAILURE) {
> + isset = 0;
> + }
> + } else {
> isset = 0;
> }
> } else {
> - target_symbol_table =
> zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
> - if (zend_hash_find(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
> - isset = 0;
> + HashTable *target_symbol_table;
> +
> + zval tmp, *varname = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_IS
> TSRMLS_CC);
> +
> + if (Z_TYPE_P(varname) != IS_STRING) {
> + tmp = *varname;
> + zval_copy_ctor(&tmp);
> + convert_to_string(&tmp);
> + varname = &tmp;
> + }
> +
> + if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) {
> + value =
> zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry,
> Z_STRVAL_P(varname), Z_STRLEN_P(varname), 1 TSRMLS_CC);
> + if (!value) {
> + isset = 0;
> + }
> + } else {
> + target_symbol_table =
> zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
> + if (zend_hash_find(target_symbol_table,
> varname->value.str.val, varname->value.str.len+1, (void **) &value) == FAILURE) {
> + isset = 0;
> + }
> }
> +
> + if (varname == &tmp) {
> + zval_dtor(&tmp);
> + }
> +
> }
>
> Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
> @@ -22046,10 +22253,6 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_C
> break;
> }
>
> - if (varname == &tmp) {
> - zval_dtor(&tmp);
> - }
> -
> ZEND_VM_NEXT_OPCODE();
> }
>
> @@ -31985,31 +32188,31 @@ void zend_init_opcodes_handlers(void)
> ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER,
> ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER,
> ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> - ZEND_CATCH_SPEC_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_CATCH_SPEC_CV_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_CATCH_SPEC_CV_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_CATCH_SPEC_CV_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_CATCH_SPEC_CV_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_NULL_HANDLER,
> + ZEND_CATCH_SPEC_CV_HANDLER,
> ZEND_THROW_SPEC_CONST_HANDLER,
> ZEND_THROW_SPEC_CONST_HANDLER,
> ZEND_THROW_SPEC_CONST_HANDLER,
> Index: Zend/zend_vm_execute.skl
> ===================================================================
> RCS file: /repository/ZendEngine2/zend_vm_execute.skl,v
> retrieving revision 1.2.2.2.2.1.2.6
> diff -u -p -d -r1.2.2.2.2.1.2.6 zend_vm_execute.skl
> --- Zend/zend_vm_execute.skl 24 Jan 2008 09:41:39 -0000 1.2.2.2.2.1.2.6
> +++ Zend/zend_vm_execute.skl 25 Apr 2008 13:02:30 -0000
> @@ -14,12 +14,12 @@ ZEND_API void {%EXECUTOR_NAME%}(zend_op_
> /* Initialize execute_data */
> execute_data = (zend_execute_data *)zend_vm_stack_alloc(
> sizeof(zend_execute_data) +
> - sizeof(zval**) * op_array->last_var +
> + sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2) +
> sizeof(temp_variable) * op_array->T TSRMLS_CC);
>
> EX(CVs) = (zval***)((char*)execute_data + sizeof(zend_execute_data));
> memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var);
> - EX(Ts) = (temp_variable *)(EX(CVs) + op_array->last_var);
> + EX(Ts) = (temp_variable *)(EX(CVs) + op_array->last_var * (EG(active_symbol_table) ?
> 1 : 2));
> EX(fbc) = NULL;
> EX(called_scope) = NULL;
> EX(object) = NULL;
> @@ -37,7 +37,7 @@ ZEND_API void {%EXECUTOR_NAME%}(zend_op_
> ZEND_VM_SET_OPCODE(op_array->opcodes);
> }
>
> - if (op_array->uses_this && EG(This)) {
> + if (op_array->uses_this && EG(This) && EG(active_symbol_table)) {
> Z_ADDREF_P(EG(This)); /* For $this pointer */
> if (zend_hash_add(EG(active_symbol_table), "this",
> sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) {
> Z_DELREF_P(EG(This));
> Index: ext/curl/streams.c
> ===================================================================
> RCS file: /repository/php-src/ext/curl/streams.c,v
> retrieving revision 1.14.2.2.2.11.2.1
> diff -u -p -d -r1.14.2.2.2.11.2.1 streams.c
> --- ext/curl/streams.c 31 Dec 2007 07:17:06 -0000 1.14.2.2.2.11.2.1
> +++ ext/curl/streams.c 25 Apr 2008 13:02:31 -0000
> @@ -64,6 +64,9 @@ static size_t on_data_available(char *da
> if (curlstream->readbuffer.writepos == 0) {
> zval *sym;
>
> + if (!EG(active_symbol_table)) {
> + zend_rebuild_symbol_table();
> + }
> MAKE_STD_ZVAL(sym);
> *sym = *curlstream->headers;
> zval_copy_ctor(sym);
> Index: ext/standard/array.c
> ===================================================================
> RCS file: /repository/php-src/ext/standard/array.c,v
> retrieving revision 1.308.2.21.2.37.2.27
> diff -u -p -d -r1.308.2.21.2.37.2.27 array.c
> --- ext/standard/array.c 12 Mar 2008 19:18:42 -0000 1.308.2.21.2.37.2.27
> +++ ext/standard/array.c 25 Apr 2008 13:02:34 -0000
> @@ -1331,6 +1331,10 @@ PHP_FUNCTION(extract)
> }
> }
>
> + if (!EG(active_symbol_table)) {
> + zend_rebuild_symbol_table();
> + }
> +
> zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(var_array), &pos);
> while (zend_hash_get_current_data_ex(Z_ARRVAL_P(var_array), (void **)&entry,
> &pos) == SUCCESS) {
> zval final_name;
> @@ -1493,6 +1497,10 @@ PHP_FUNCTION(compact)
> WRONG_PARAM_COUNT;
> }
>
> + if (!EG(active_symbol_table)) {
> + zend_rebuild_symbol_table();
> + }
> +
> array_init(return_value);
>
> for (i=0; i<ZEND_NUM_ARGS(); i++) {
> Index: ext/standard/http_fopen_wrapper.c
> ===================================================================
> RCS file: /repository/php-src/ext/standard/http_fopen_wrapper.c,v
> retrieving revision 1.99.2.12.2.9.2.6
> diff -u -p -d -r1.99.2.12.2.9.2.6 http_fopen_wrapper.c
> --- ext/standard/http_fopen_wrapper.c 6 Apr 2008 15:21:24 -0000 1.99.2.12.2.9.2.6
> +++ ext/standard/http_fopen_wrapper.c 25 Apr 2008 13:02:35 -0000
> @@ -494,6 +494,10 @@ php_stream *php_stream_url_wrap_http_ex(
>
> location[0] = '\0';
>
> + if (!EG(active_symbol_table)) {
> + zend_rebuild_symbol_table();
> + }
> +
> if (header_init) {
> zval *tmp;
> MAKE_STD_ZVAL(tmp);
> Index: ext/standard/string.c
> ===================================================================
> RCS file: /repository/php-src/ext/standard/string.c,v
> retrieving revision 1.445.2.14.2.69.2.19
> diff -u -p -d -r1.445.2.14.2.69.2.19 string.c
> --- ext/standard/string.c 10 Mar 2008 22:12:36 -0000 1.445.2.14.2.69.2.19
> +++ ext/standard/string.c 25 Apr 2008 13:02:36 -0000
> @@ -4178,8 +4178,11 @@ PHP_FUNCTION(parse_str)
>
> if (argCount == 1) {
> zval tmp;
> - Z_ARRVAL(tmp) = EG(active_symbol_table);
>
> + if (!EG(active_symbol_table)) {
> + zend_rebuild_symbol_table();
> + }
> + Z_ARRVAL(tmp) = EG(active_symbol_table);
> sapi_module.treat_data(PARSE_STRING, res, &tmp TSRMLS_CC);
> } else {
> /* Clear out the array that was passed in. */
> Index: ext/wddx/wddx.c
> ===================================================================
> RCS file: /repository/php-src/ext/wddx/wddx.c,v
> retrieving revision 1.119.2.10.2.17.2.4
> diff -u -p -d -r1.119.2.10.2.17.2.4 wddx.c
> --- ext/wddx/wddx.c 20 Jan 2008 15:33:24 -0000 1.119.2.10.2.17.2.4
> +++ ext/wddx/wddx.c 25 Apr 2008 13:02:38 -0000
> @@ -659,6 +659,9 @@ static void php_wddx_add_var(wddx_packet
>
> if (Z_TYPE_P(name_var) == IS_STRING)
> {
> + if (!EG(active_symbol_table)) {
> + zend_rebuild_symbol_table();
> + }
> if (zend_hash_find(EG(active_symbol_table), Z_STRVAL_P(name_var),
>
> Z_STRLEN_P(name_var)+1, (void**)&val) != FAILURE) {
> php_wddx_serialize_var(packet, *val,
> Z_STRVAL_P(name_var), Z_STRLEN_P(name_var) TSRMLS_CC);
> Index: main/php_variables.c
> ===================================================================
> RCS file: /repository/php-src/main/php_variables.c,v
> retrieving revision 1.104.2.10.2.11.2.4
> diff -u -p -d -r1.104.2.10.2.11.2.4 php_variables.c
> --- main/php_variables.c 12 Mar 2008 20:24:45 -0000 1.104.2.10.2.11.2.4
> +++ main/php_variables.c 25 Apr 2008 13:02:38 -0000
> @@ -72,6 +72,9 @@ PHPAPI void php_register_variable_ex(cha
> if (track_vars_array) {
> symtable1 = Z_ARRVAL_P(track_vars_array);
> } else if (PG(register_globals)) {
> + if (!EG(active_symbol_table)) {
> + zend_rebuild_symbol_table(TSRMLS_C);
> + }
> symtable1 = EG(active_symbol_table);
> }
> if (!symtable1) {
Best regards,
Marcus