]> granicus.if.org Git - php/commitdiff
Lazy EG(active_symbol_table) initialization
authorDmitry Stogov <dmitry@php.net>
Tue, 29 Apr 2008 08:15:49 +0000 (08:15 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 29 Apr 2008 08:15:49 +0000 (08:15 +0000)
16 files changed:
Zend/zend.c
Zend/zend_API.h
Zend/zend_builtin_functions.c
Zend/zend_compile.c
Zend/zend_execute.c
Zend/zend_execute_API.c
Zend/zend_hash.h
Zend/zend_object_handlers.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_execute.skl
ext/curl/streams.c
ext/standard/array.c
ext/standard/http_fopen_wrapper.c
ext/standard/string.c
ext/wddx/wddx.c

index 64bf6c1ca3ddc8b31c6cd3d228f82f5d4da93fd7..7910265d1312158fd4006e889d81046f2793eacc 100644 (file)
@@ -1589,6 +1589,9 @@ ZEND_API void zend_error(int type, const char *format, ...) /* {{{ */
                        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 fc6d0638b2b83111fe84267b04aaefca32429cce..45c76760130a0928a2e110231bedf29c8d43c980 100644 (file)
@@ -1591,6 +1591,8 @@ ZEND_API int zend_u_delete_global_variable(zend_uchar type, zstr name, int name_
 
 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 10644661f148aefc7088c27a574480d0b676b561..f8ffebfa2687b99cd305f479cfe13364d917da81 100644 (file)
@@ -1501,6 +1501,10 @@ ZEND_FUNCTION(get_defined_vars)
 
        array_init(return_value);
 
+       if (!EG(active_symbol_table)) {
+               zend_rebuild_symbol_table(TSRMLS_C);
+       }
+
        zend_hash_copy(Z_ARRVAL_P(return_value), EG(active_symbol_table),
                                        (copy_ctor_func_t)zval_add_ref, &tmp, sizeof(zval *));
 }
index b7b4c40584ca9f4e616d5603e7987f8cf9a3aa67..a8ac9ebde19e3e2d70b2f9558265472a7d5746ae 100644 (file)
@@ -2282,7 +2282,9 @@ void zend_do_begin_catch(znode *try_token, znode *class_name, znode *catch_var,
        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), Z_TYPE(catch_var->u.constant), Z_UNIVAL(catch_var->u.constant), Z_UNILEN(catch_var->u.constant));
+       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;
@@ -2660,7 +2662,7 @@ static zend_bool do_inherit_property_access_check(HashTable *target_ht, zend_pro
 
                                if (zend_u_hash_quick_find(&parent_ce->default_properties, utype, parent_info->name, parent_info->name_length+1, parent_info->h, (void **) &pvalue) == SUCCESS) {
                                        Z_ADDREF_PP(pvalue);
-                                       zend_u_hash_del(&ce->default_properties, utype, child_info->name, child_info->name_length+1);
+                                       zend_u_hash_quick_del(&ce->default_properties, utype, child_info->name, child_info->name_length+1, parent_info->h);
                                        zend_u_hash_quick_update(&ce->default_properties, utype, parent_info->name, parent_info->name_length+1, parent_info->h, pvalue, sizeof(zval *), NULL);
                                }
                        }
@@ -4366,18 +4368,12 @@ void zend_do_unset(znode *variable TSRMLS_DC) /* {{{ */
        zend_check_writable_variable(variable);
 
        if (variable->op_type == IS_CV) {
-               zstr name;
-               int name_len;
                zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 
-               name = CG(active_op_array)->vars[variable->u.var].name;
-               name_len = CG(active_op_array)->vars[variable->u.var].name_len;
-
                opline->opcode = ZEND_UNSET_VAR;
-               opline->op1.op_type = IS_CONST;
-               ZVAL_TEXTL(&opline->op1.u.constant, name, name_len, 1);
+               opline->op1 = *variable;
                SET_UNUSED(opline->op2);
-               opline->op2.u.EA.type = zend_u_is_auto_global(ZEND_STR_TYPE, name, name_len TSRMLS_CC) ? ZEND_FETCH_GLOBAL : ZEND_FETCH_LOCAL;;
+               opline->op2.u.EA.type = ZEND_FETCH_LOCAL;
                SET_UNUSED(opline->result);
        } else {
                last_op = &CG(active_op_array)->opcodes[get_next_op_number(CG(active_op_array))-1];
@@ -4407,19 +4403,11 @@ void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC
        zend_check_writable_variable(variable);
 
        if (variable->op_type == IS_CV) {
-               zstr name;
-               int name_len;
-
                last_op = get_next_op(CG(active_op_array) TSRMLS_CC);
-
-               name = CG(active_op_array)->vars[variable->u.var].name;
-               name_len = CG(active_op_array)->vars[variable->u.var].name_len;
-
                last_op->opcode = ZEND_ISSET_ISEMPTY_VAR;
-               last_op->op1.op_type = IS_CONST;
-               ZVAL_TEXTL(&last_op->op1.u.constant, name, name_len, 1);
+               last_op->op1 = *variable;
                SET_UNUSED(last_op->op2);
-               last_op->op2.u.EA.type = zend_u_is_auto_global(ZEND_STR_TYPE, name, name_len TSRMLS_CC) ? ZEND_FETCH_GLOBAL : ZEND_FETCH_LOCAL;;
+               last_op->op2.u.EA.type = ZEND_FETCH_LOCAL;
                last_op->result.u.var = get_temporary_variable(CG(active_op_array));
        } else {
                last_op = &CG(active_op_array)->opcodes[get_next_op_number(CG(active_op_array))-1];
index 1e3654e6d22f1275c871b51ac6bd1bc3a4af59e8..ce7a511b5cf0e8c76eb6fb1e6689f99dc3290018 100644 (file)
@@ -173,15 +173,6 @@ ZEND_API zval** zend_get_compiled_variable_value(zend_execute_data *execute_data
 }
 /* }}} */
 
-static inline void zend_get_cv_address(zend_uchar utype, zend_compiled_variable *cv, zval ***ptr, temp_variable *Ts TSRMLS_DC) /* {{{ */
-{
-       zval *new_zval = &EG(uninitialized_zval);
-
-       Z_ADDREF_P(new_zval);
-       zend_u_hash_quick_update(EG(active_symbol_table), utype, 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;
@@ -246,7 +237,8 @@ static inline zval *_get_zval_ptr_cv(znode *node, temp_variable *Ts, int type TS
                zend_compiled_variable *cv = &CV_DEF_OF(node->u.var);
                zend_uchar utype = UG(unicode)?IS_UNICODE:IS_STRING;
 
-               if (zend_u_hash_quick_find(EG(active_symbol_table), utype, cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
+               if (!EG(active_symbol_table) ||
+                   zend_u_hash_quick_find(EG(active_symbol_table), utype, cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
                        switch (type) {
                                case BP_VAR_R:
                                case BP_VAR_UNSET:
@@ -259,7 +251,13 @@ static inline zval *_get_zval_ptr_cv(znode *node, temp_variable *Ts, int type TS
                                        zend_error(E_NOTICE, "Undefined variable: %v", cv->name);
                                        /* break missing intentionally */
                                case BP_VAR_W:
-                                       zend_get_cv_address(utype, 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_u_hash_quick_update(EG(active_symbol_table), utype, cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr);
+                                       }
                                        break;
                        }
                }
@@ -319,7 +317,8 @@ static inline zval **_get_zval_ptr_ptr_cv(znode *node, temp_variable *Ts, int ty
                zend_compiled_variable *cv = &CV_DEF_OF(node->u.var);
                zend_uchar utype = UG(unicode)?IS_UNICODE:IS_STRING;
 
-               if (zend_u_hash_quick_find(EG(active_symbol_table), utype, cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
+               if (!EG(active_symbol_table) ||
+                   zend_u_hash_quick_find(EG(active_symbol_table), utype, cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
                        switch (type) {
                                case BP_VAR_R:
                                case BP_VAR_UNSET:
@@ -332,7 +331,13 @@ static inline zval **_get_zval_ptr_ptr_cv(znode *node, temp_variable *Ts, int ty
                                        zend_error(E_NOTICE, "Undefined variable: %v", cv->name);
                                        /* break missing intentionally */
                                case BP_VAR_W:
-                                       zend_get_cv_address(utype, 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_u_hash_quick_update(EG(active_symbol_table), utype, cv->name, cv->name_len+1, cv->hash_value, &EG(uninitialized_zval_ptr), sizeof(zval *), (void **)ptr);
+                                       }
                                        break;
                        }
                }
@@ -843,6 +848,9 @@ static inline HashTable *zend_get_target_symbol_table(zend_op *opline, temp_vari
 {
        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:
@@ -1408,11 +1416,21 @@ ZEND_API void execute_internal(zend_execute_data *execute_data_ptr, int return_v
 #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 ae76c28bf00e2f58042b892419d2a17609bfa0fa..b3a329b05fba9073441dbbc407a74ebbd98488a4 100644 (file)
@@ -1996,7 +1996,7 @@ ZEND_API int zend_u_delete_global_variable(zend_uchar type, zstr name, int name_
                                }
                        }
                }
-               return zend_u_hash_del(&EG(symbol_table), type, name, name_len + 1);
+               return zend_u_hash_quick_del(&EG(symbol_table), type, name, name_len + 1, hash_value);
        }
        return FAILURE;
 }
@@ -2008,6 +2008,45 @@ ZEND_API int zend_delete_global_variable(char *name, int name_len TSRMLS_DC) /*
 }
 /* }}} */
 
+ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */
+{
+       zend_uchar type = ZEND_STR_TYPE;
+       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_ascii_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_u_hash_quick_update(EG(active_symbol_table),
+                                               type,
+                                               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 bf65381beca0bc2570e06b5ecf129611a9db4c2b..3445560246d1c6962af44979c90c27630f2590f6 100644 (file)
@@ -36,6 +36,7 @@
 
 #define HASH_DEL_KEY 0
 #define HASH_DEL_INDEX 1
+#define HASH_DEL_KEY_QUICK 2
 
 
 
@@ -195,8 +196,12 @@ ZEND_API int zend_utf8_hash_del(HashTable *ht, const char *arKey, uint nKeyLengt
 ZEND_API int zend_u_hash_del_key_or_index(HashTable *ht, zend_uchar type, zstr 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_u_hash_del(ht, type, arKey, nKeyLength) \
                zend_u_hash_del_key_or_index(ht, type, arKey, nKeyLength, 0, HASH_DEL_KEY)
+#define zend_u_hash_quick_del(ht, type, arKey, nKeyLength, h) \
+               zend_u_hash_del_key_or_index(ht, type, 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 21c77f382499c350e1e678b0de53f0aaed67e8a0..a57883f80728c9c25e7cebb62dbedd459285170c 100644 (file)
@@ -620,7 +620,7 @@ static void zend_std_unset_property(zval *object, zval *member TSRMLS_DC) /* {{{
 
        property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__unset != NULL) TSRMLS_CC);
 
-       if (!property_info || zend_u_hash_del(zobj->properties, Z_TYPE_P(member), property_info->name, property_info->name_length+1)) {
+       if (!property_info || zend_u_hash_quick_del(zobj->properties, Z_TYPE_P(member), property_info->name, property_info->name_length+1, property_info->h)) {
                zend_guard *guard;
 
                if (zobj->ce->__unset &&
index fad07c3e73261b3ecb6cfc29b1b90439da883e6a..287543fc765a548395686678bd48d91f9b34800b 100644 (file)
@@ -2212,14 +2212,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
        } 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_u_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
-                       /*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)) {                        
@@ -2234,14 +2227,16 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
                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 */
@@ -2427,7 +2422,7 @@ ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
        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;
@@ -2449,8 +2444,17 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, ANY, ANY)
                }
        }
 
-       zend_u_hash_update(EG(active_symbol_table), Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant),
-               Z_UNILEN(opline->op2.u.constant)+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_u_hash_quick_update(EG(active_symbol_table), ZEND_STR_TYPE, cv->name, cv->name_len+1, cv->hash_value,
+                   &EG(exception), sizeof(zval *), NULL);
+       }
        EG(exception) = NULL;
        ZEND_VM_NEXT_OPCODE();
 }
@@ -3203,6 +3207,10 @@ skip_compile:
                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;
@@ -3244,6 +3252,36 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, ANY)
        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_u_hash_quick_del(EG(active_symbol_table), ZEND_STR_TYPE, 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.v, cv->name.v, USTR_BYTES(ZEND_STR_TYPE, 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 && Z_TYPE_P(varname) != IS_UNICODE) {
@@ -3251,17 +3289,18 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, ANY)
                zval_copy_ctor(&tmp);
                convert_to_text(&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_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname) TSRMLS_CC);
        } else {
+               ulong hash_value = zend_u_inline_hash_func(Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1);
+
                target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
-               if (zend_u_hash_del(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1) == SUCCESS) {
+               if (zend_u_hash_quick_del(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, hash_value) == SUCCESS) {
                        zend_execute_data *ex = EXECUTE_DATA;
-                       ulong hash_value = zend_u_inline_hash_func(Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1);
                        zend_auto_global *auto_global;
 
                        if (zend_u_hash_quick_find(CG(auto_globals), Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, hash_value, (void**)&auto_global) == SUCCESS) {
@@ -3287,7 +3326,7 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, ANY)
 
        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();
@@ -3754,29 +3793,49 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
 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 && Z_TYPE_P(varname) != IS_UNICODE) {
-               tmp = *varname;
-               zval_copy_ctor(&tmp);
-               convert_to_text(&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_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname), 1 TSRMLS_CC);
-               if (!value) {
-                       isset = 0;
+                       if (zend_u_hash_quick_find(EG(active_symbol_table), ZEND_STR_TYPE, cv->name, cv->name_len+1, cv->hash_value, (void **) &value) == FAILURE) {
+                               isset = 0;
+                       }
+               } else {                
+                       isset = 0;
+               }
+       } else {
+               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 && Z_TYPE_P(varname) != IS_UNICODE) {
+                       tmp = *varname;
+                       zval_copy_ctor(&tmp);
+                       convert_to_text(&tmp);
+                       varname = &tmp;
                }
-       } else {
-               target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
-               if (zend_u_hash_find(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, (void **) &value) == FAILURE) {
-                       isset = 0;
+
+               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_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_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_u_hash_find(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+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;
@@ -3798,11 +3857,6 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, ANY)
                        break;
        }
 
-       if (varname == &tmp) {
-               zval_dtor(&tmp);
-       }
-       FREE_OP1();
-
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -4187,10 +4241,8 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
        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 b7a7aa4d0ec482943f52f031348951b61b13ee9b..933f06b821f94e4d6aff202c2b73252e808e9890 100644 (file)
@@ -46,12 +46,12 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
        /* 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_array TSRMLS_DC)
                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_ascii_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) {
                        Z_DELREF_P(EG(This));
@@ -205,14 +205,7 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
        } 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_u_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
-                       /*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)) {
@@ -227,14 +220,16 @@ static int zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
                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 */
@@ -303,34 +298,6 @@ static int ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        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_u_hash_update(EG(active_symbol_table), Z_TYPE(opline->op2.u.constant), Z_UNIVAL(opline->op2.u.constant),
-               Z_UNILEN(opline->op2.u.constant)+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);
@@ -511,10 +478,8 @@ static int ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        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);
@@ -1055,6 +1020,43 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        ZEND_VM_NEXT_OPCODE();
 }
 
+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_u_hash_quick_update(EG(active_symbol_table), ZEND_STR_TYPE, cv->name, cv->name_len+1, cv->hash_value,
+                   &EG(exception), sizeof(zval *), NULL);
+       }
+       EG(exception) = NULL;
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_BW_NOT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        zend_op *opline = EX(opline);
@@ -1757,6 +1759,10 @@ skip_compile:
                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;
@@ -1798,6 +1804,36 @@ static int ZEND_UNSET_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        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_u_hash_quick_del(EG(active_symbol_table), ZEND_STR_TYPE, 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.v, cv->name.v, USTR_BYTES(ZEND_STR_TYPE, 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 && Z_TYPE_P(varname) != IS_UNICODE) {
@@ -1805,17 +1841,18 @@ static int ZEND_UNSET_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zval_copy_ctor(&tmp);
                convert_to_text(&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_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname) TSRMLS_CC);
        } else {
+               ulong hash_value = zend_u_inline_hash_func(Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1);
+
                target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
-               if (zend_u_hash_del(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1) == SUCCESS) {
+               if (zend_u_hash_quick_del(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, hash_value) == SUCCESS) {
                        zend_execute_data *ex = execute_data;
-                       ulong hash_value = zend_u_inline_hash_func(Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1);
                        zend_auto_global *auto_global;
 
                        if (zend_u_hash_quick_find(CG(auto_globals), Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, hash_value, (void**)&auto_global) == SUCCESS) {
@@ -1841,7 +1878,7 @@ static int ZEND_UNSET_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        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);
        }
 
@@ -2003,29 +2040,49 @@ static int ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 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 && Z_TYPE_P(varname) != IS_UNICODE) {
-               tmp = *varname;
-               zval_copy_ctor(&tmp);
-               convert_to_text(&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_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname), 1 TSRMLS_CC);
-               if (!value) {
-                       isset = 0;
+                       if (zend_u_hash_quick_find(EG(active_symbol_table), ZEND_STR_TYPE, cv->name, cv->name_len+1, cv->hash_value, (void **) &value) == FAILURE) {
+                               isset = 0;
+                       }
+               } else {
+                       isset = 0;
+               }
+       } else {
+               HashTable *target_symbol_table;
+
+               zval tmp, *varname = &opline->op1.u.constant;
+
+               if (Z_TYPE_P(varname) != IS_STRING && Z_TYPE_P(varname) != IS_UNICODE) {
+                       tmp = *varname;
+                       zval_copy_ctor(&tmp);
+                       convert_to_text(&tmp);
+                       varname = &tmp;
                }
-       } else {
-               target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
-               if (zend_u_hash_find(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, (void **) &value) == FAILURE) {
-                       isset = 0;
+
+               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_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_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_u_hash_find(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, (void **) &value) == FAILURE) {
+                               isset = 0;
+                       }
                }
+
+               if (varname == &tmp) {
+                       zval_dtor(&tmp);
+               }
+
        }
 
        Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
@@ -2047,10 +2104,6 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        break;
        }
 
-       if (varname == &tmp) {
-               zval_dtor(&tmp);
-       }
-
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -5066,6 +5119,10 @@ skip_compile:
                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;
@@ -5107,6 +5164,36 @@ static int ZEND_UNSET_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        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_u_hash_quick_del(EG(active_symbol_table), ZEND_STR_TYPE, 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.v, cv->name.v, USTR_BYTES(ZEND_STR_TYPE, 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 && Z_TYPE_P(varname) != IS_UNICODE) {
@@ -5114,17 +5201,18 @@ static int ZEND_UNSET_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zval_copy_ctor(&tmp);
                convert_to_text(&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_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname) TSRMLS_CC);
        } else {
+               ulong hash_value = zend_u_inline_hash_func(Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1);
+
                target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
-               if (zend_u_hash_del(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1) == SUCCESS) {
+               if (zend_u_hash_quick_del(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, hash_value) == SUCCESS) {
                        zend_execute_data *ex = execute_data;
-                       ulong hash_value = zend_u_inline_hash_func(Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1);
                        zend_auto_global *auto_global;
 
                        if (zend_u_hash_quick_find(CG(auto_globals), Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, hash_value, (void**)&auto_global) == SUCCESS) {
@@ -5150,7 +5238,7 @@ static int ZEND_UNSET_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        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);
@@ -5312,29 +5400,49 @@ static int ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 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 && Z_TYPE_P(varname) != IS_UNICODE) {
-               tmp = *varname;
-               zval_copy_ctor(&tmp);
-               convert_to_text(&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_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname), 1 TSRMLS_CC);
-               if (!value) {
-                       isset = 0;
+                       if (zend_u_hash_quick_find(EG(active_symbol_table), ZEND_STR_TYPE, cv->name, cv->name_len+1, cv->hash_value, (void **) &value) == FAILURE) {
+                               isset = 0;
+                       }
+               } else {
+                       isset = 0;
+               }
+       } else {
+               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 && Z_TYPE_P(varname) != IS_UNICODE) {
+                       tmp = *varname;
+                       zval_copy_ctor(&tmp);
+                       convert_to_text(&tmp);
+                       varname = &tmp;
                }
-       } else {
-               target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
-               if (zend_u_hash_find(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, (void **) &value) == FAILURE) {
-                       isset = 0;
+
+               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_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_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_u_hash_find(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+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;
@@ -5356,11 +5464,6 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        break;
        }
 
-       if (varname == &tmp) {
-               zval_dtor(&tmp);
-       }
-       zval_dtor(free_op1.var);
-
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -8409,6 +8512,10 @@ skip_compile:
                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;
@@ -8450,6 +8557,36 @@ static int ZEND_UNSET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        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_u_hash_quick_del(EG(active_symbol_table), ZEND_STR_TYPE, 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.v, cv->name.v, USTR_BYTES(ZEND_STR_TYPE, 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 && Z_TYPE_P(varname) != IS_UNICODE) {
@@ -8457,17 +8594,18 @@ static int ZEND_UNSET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zval_copy_ctor(&tmp);
                convert_to_text(&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_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname) TSRMLS_CC);
        } else {
+               ulong hash_value = zend_u_inline_hash_func(Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1);
+
                target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
-               if (zend_u_hash_del(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1) == SUCCESS) {
+               if (zend_u_hash_quick_del(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, hash_value) == SUCCESS) {
                        zend_execute_data *ex = execute_data;
-                       ulong hash_value = zend_u_inline_hash_func(Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1);
                        zend_auto_global *auto_global;
 
                        if (zend_u_hash_quick_find(CG(auto_globals), Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, hash_value, (void**)&auto_global) == SUCCESS) {
@@ -8493,7 +8631,7 @@ static int ZEND_UNSET_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        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);};
@@ -8811,29 +8949,49 @@ static int ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 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 && Z_TYPE_P(varname) != IS_UNICODE) {
-               tmp = *varname;
-               zval_copy_ctor(&tmp);
-               convert_to_text(&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_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname), 1 TSRMLS_CC);
-               if (!value) {
-                       isset = 0;
+                       if (zend_u_hash_quick_find(EG(active_symbol_table), ZEND_STR_TYPE, cv->name, cv->name_len+1, cv->hash_value, (void **) &value) == FAILURE) {
+                               isset = 0;
+                       }
+               } else {
+                       isset = 0;
+               }
+       } else {
+               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 && Z_TYPE_P(varname) != IS_UNICODE) {
+                       tmp = *varname;
+                       zval_copy_ctor(&tmp);
+                       convert_to_text(&tmp);
+                       varname = &tmp;
                }
-       } else {
-               target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
-               if (zend_u_hash_find(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, (void **) &value) == FAILURE) {
-                       isset = 0;
+
+               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_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_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_u_hash_find(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+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;
@@ -8855,11 +9013,6 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        break;
        }
 
-       if (varname == &tmp) {
-               zval_dtor(&tmp);
-       }
-       if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
-
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -22667,6 +22820,10 @@ skip_compile:
                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;
@@ -22708,6 +22865,36 @@ static int ZEND_UNSET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
        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_u_hash_quick_del(EG(active_symbol_table), ZEND_STR_TYPE, 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.v, cv->name.v, USTR_BYTES(ZEND_STR_TYPE, 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 && Z_TYPE_P(varname) != IS_UNICODE) {
@@ -22715,17 +22902,18 @@ static int ZEND_UNSET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                zval_copy_ctor(&tmp);
                convert_to_text(&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_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname) TSRMLS_CC);
        } else {
+               ulong hash_value = zend_u_inline_hash_func(Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1);
+
                target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
-               if (zend_u_hash_del(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1) == SUCCESS) {
+               if (zend_u_hash_quick_del(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, hash_value) == SUCCESS) {
                        zend_execute_data *ex = execute_data;
-                       ulong hash_value = zend_u_inline_hash_func(Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1);
                        zend_auto_global *auto_global;
 
                        if (zend_u_hash_quick_find(CG(auto_globals), Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, hash_value, (void**)&auto_global) == SUCCESS) {
@@ -22751,7 +22939,7 @@ static int ZEND_UNSET_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 
        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);
        }
 
@@ -22913,29 +23101,49 @@ static int ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 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 && Z_TYPE_P(varname) != IS_UNICODE) {
-               tmp = *varname;
-               zval_copy_ctor(&tmp);
-               convert_to_text(&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_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname), 1 TSRMLS_CC);
-               if (!value) {
-                       isset = 0;
+                       if (zend_u_hash_quick_find(EG(active_symbol_table), ZEND_STR_TYPE, cv->name, cv->name_len+1, cv->hash_value, (void **) &value) == FAILURE) {
+                               isset = 0;
+                       }
+               } else {
+                       isset = 0;
+               }
+       } else {
+               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 && Z_TYPE_P(varname) != IS_UNICODE) {
+                       tmp = *varname;
+                       zval_copy_ctor(&tmp);
+                       convert_to_text(&tmp);
+                       varname = &tmp;
                }
-       } else {
-               target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), BP_VAR_IS, varname TSRMLS_CC);
-               if (zend_u_hash_find(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, (void **) &value) == FAILURE) {
-                       isset = 0;
+
+               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_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_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_u_hash_find(target_symbol_table, Z_TYPE_P(varname), Z_UNIVAL_P(varname), Z_UNILEN_P(varname)+1, (void **) &value) == FAILURE) {
+                               isset = 0;
+                       }
                }
+
+               if (varname == &tmp) {
+                       zval_dtor(&tmp);
+               }
+
        }
 
        Z_TYPE(EX_T(opline->result.u.var).tmp_var) = IS_BOOL;
@@ -22957,10 +23165,6 @@ static int ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
                        break;
        }
 
-       if (varname == &tmp) {
-               zval_dtor(&tmp);
-       }
-
        ZEND_VM_NEXT_OPCODE();
 }
 
@@ -33185,31 +33389,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 dce15d9f4f00dae254092fda91baee1992427425..911b01f7f385148832c171b05e2d216b95acd11c 100644 (file)
@@ -14,12 +14,12 @@ ZEND_API void {%EXECUTOR_NAME%}(zend_op_array *op_array TSRMLS_DC)
        /* 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_array *op_array TSRMLS_DC)
                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_ascii_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) {
                        Z_DELREF_P(EG(This));
index 1271bfcf60a671a3cf8916510590fa4c27413295..d55d94647511ba68986d7897c761a9072a6015d3 100644 (file)
@@ -64,6 +64,9 @@ static size_t on_data_available(char *data, size_t size, size_t nmemb, void *ctx
        if (curlstream->readbuffer.writepos == 0) {
                zval *sym;
 
+               if (!EG(active_symbol_table)) {
+                       zend_rebuild_symbol_table(TSRMLS_C);
+               }
                MAKE_STD_ZVAL(sym);
                *sym = *curlstream->headers;
                zval_copy_ctor(sym);
index 1a4e9d4f41a8cfa210f770fedf1713c52e528ad3..5a26eea0e5424032df38ce8021a92d4053ddf402 100644 (file)
@@ -1420,6 +1420,10 @@ PHP_FUNCTION(extract)
                }
        }
 
+       if (!EG(active_symbol_table)) {
+               zend_rebuild_symbol_table(TSRMLS_C);
+       }
+
        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;
@@ -1617,6 +1621,10 @@ PHP_FUNCTION(compact)
                WRONG_PARAM_COUNT;
        }
 
+       if (!EG(active_symbol_table)) {
+               zend_rebuild_symbol_table(TSRMLS_C);
+       }
+
        array_init(return_value);
 
        for (i=0; i<ZEND_NUM_ARGS(); i++) {
index cb6c4a7b640fa0448eb749e7235a24ade313e52a..18fa9292bd89b0ac3c3f82407df233370068d50a 100644 (file)
@@ -537,6 +537,10 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path,
 
        location[0] = '\0';
 
+       if (!EG(active_symbol_table)) {
+               zend_rebuild_symbol_table(TSRMLS_C);
+       }
+
        if (header_init) {
                zval *tmp;
                MAKE_STD_ZVAL(tmp);
index 03679e74bb0a3a9a882e3ba77d59d1201e62dc93..81a6422192a288ca18799f87f873c144deb08318 100644 (file)
@@ -6265,8 +6265,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(TSRMLS_C);
+               }
+               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 c55fb4496782d69c1f0bb66aba40d7f4d714be95..4273c3b907ab62051be1b552b3dac16528a35687 100644 (file)
@@ -660,6 +660,9 @@ static void php_wddx_add_var(wddx_packet *packet, zval *name_var)
        
        if (Z_TYPE_P(name_var) == IS_STRING)
        {
+               if (!EG(active_symbol_table)) {
+                       zend_rebuild_symbol_table(TSRMLS_C);
+               }
                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);