mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Lazy EG(active_symbol_table) initialization
This commit is contained in:
parent
c75658c477
commit
2ecf4bb0a7
18 changed files with 596 additions and 252 deletions
1
NEWS
1
NEWS
|
@ -101,6 +101,7 @@ PHP NEWS
|
|||
- Added forward_static_call(_array) to complete LSB. (Mike Lively)
|
||||
|
||||
- Improved PHP runtime speed and memory usage:
|
||||
. Lazy EG(active_symbol_table) initialization. (Dmitry)
|
||||
. Optimized ZEND_RETURN opcode to not allocate and copy return value if it is
|
||||
not used. (Dmitry)
|
||||
. Replaced flex based scanner with re2c based scanner. (Marcus, Nuno, Scott)
|
||||
|
|
|
@ -1071,6 +1071,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);
|
||||
|
|
|
@ -464,6 +464,8 @@ ZEND_API int zend_delete_global_variable(char *name, int name_len TSRMLS_DC);
|
|||
|
||||
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);
|
||||
|
|
|
@ -1485,6 +1485,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 *));
|
||||
}
|
||||
|
|
|
@ -2178,7 +2178,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), 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_access_check(HashTable *target_ht, zend_pro
|
|||
|
||||
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 TSRMLS_DC)
|
|||
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, znode *result, znode *variable TSRMLS_DC
|
|||
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));
|
||||
|
|
|
@ -169,14 +169,6 @@ ZEND_API zval** zend_get_compiled_variable_value(zend_execute_data *execute_data
|
|||
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(znode *node, temp_variable *Ts, int type TS
|
|||
|
||||
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(znode *node, temp_variable *Ts, int type TS
|
|||
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_cv(znode *node, temp_variable *Ts, int ty
|
|||
|
||||
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_cv(znode *node, temp_variable *Ts, int ty
|
|||
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_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:
|
||||
|
@ -1298,11 +1308,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() \
|
||||
|
|
|
@ -1777,12 +1777,49 @@ ZEND_API int zend_delete_global_variable(char *name, int name_len TSRMLS_DC) /*
|
|||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
|
|
|
@ -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(HashTable *ht, apply_func_t apply_func TSR
|
|||
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)
|
||||
|
||||
|
|
|
@ -612,7 +612,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_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 &&
|
||||
|
|
|
@ -2150,15 +2150,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_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_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 */
|
||||
|
@ -2364,7 +2358,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;
|
||||
|
@ -2386,8 +2380,17 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, ANY, ANY)
|
|||
}
|
||||
}
|
||||
|
||||
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, CONST|TMP|VAR|CV, ANY)
|
|||
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, 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_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, CONST|TMP|VAR|CV, ANY)
|
|||
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, 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();
|
||||
|
@ -3619,29 +3657,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) {
|
||||
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_VAR, CONST|TMP|VAR|CV, ANY)
|
|||
break;
|
||||
}
|
||||
|
||||
if (varname == &tmp) {
|
||||
zval_dtor(&tmp);
|
||||
}
|
||||
FREE_OP1();
|
||||
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
|
@ -4024,10 +4077,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);
|
||||
|
|
|
@ -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_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_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_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_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 */
|
||||
|
@ -296,34 +290,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_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_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);
|
||||
|
@ -1076,6 +1040,43 @@ static int ZEND_INIT_FCALL_BY_NAME_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
|||
}
|
||||
|
||||
|
||||
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_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
|||
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_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_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_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
|||
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_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);
|
||||
}
|
||||
|
||||
|
@ -1969,29 +2005,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) {
|
||||
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_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
|||
break;
|
||||
}
|
||||
|
||||
if (varname == &tmp) {
|
||||
zval_dtor(&tmp);
|
||||
}
|
||||
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
|
@ -4896,6 +4948,10 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
|||
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_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_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_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
|||
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_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);
|
||||
|
@ -5138,29 +5225,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) {
|
||||
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_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
|||
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_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
|||
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_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_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_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
|||
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_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);};
|
||||
|
@ -8484,29 +8621,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) {
|
||||
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_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();
|
||||
}
|
||||
|
||||
|
@ -21760,6 +21912,10 @@ static int ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
|||
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_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_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_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
|||
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_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);
|
||||
}
|
||||
|
||||
|
@ -22002,29 +22189,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) {
|
||||
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_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
|||
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,
|
||||
|
|
|
@ -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_hash_add(EG(active_symbol_table), "this", sizeof("this"), &EG(This), sizeof(zval *), NULL)==FAILURE) {
|
||||
Z_DELREF_P(EG(This));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1331,6 +1331,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;
|
||||
|
@ -1493,6 +1497,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++) {
|
||||
|
|
|
@ -494,6 +494,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);
|
||||
|
|
|
@ -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(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. */
|
||||
|
|
|
@ -659,6 +659,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);
|
||||
|
|
|
@ -72,6 +72,9 @@ PHPAPI void php_register_variable_ex(char *var, zval *val, zval *track_vars_arra
|
|||
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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue