From: Zeev Suraski Date: Mon, 17 Feb 2003 14:06:39 +0000 (+0000) Subject: Improve handling of static member variables X-Git-Tag: RELEASE_0_5~938 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d22cc2f3293bab101dc65ed243521d7cacc5b25a;p=php Improve handling of static member variables --- diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 3f1c52e82b..961a52fd93 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -662,7 +662,7 @@ static void zend_fetch_var_address(zend_op *opline, temp_variable *Ts, int type if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) { target_symbol_table = NULL; - retval = zend_get_static_property(T(opline->op2.u.var).EA.class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), type TSRMLS_CC); + retval = zend_std_get_static_property(T(opline->op2.u.var).EA.class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0 TSRMLS_CC); } else { target_symbol_table = zend_get_target_symbol_table(opline, Ts, type, varname TSRMLS_CC); if (!target_symbol_table) { @@ -2502,7 +2502,7 @@ int zend_init_static_method_call_handler(ZEND_OPCODE_HANDLER_ARGS) ce = EX_T(EX(opline)->op1.u.var).EA.class_entry; - EX(fbc) = zend_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); + EX(fbc) = zend_std_get_static_method(ce, function_name_strval, function_name_strlen TSRMLS_CC); EX(calling_scope) = EX(fbc)->common.scope; if (!is_const) { @@ -3451,23 +3451,26 @@ int zend_include_or_eval_handler(ZEND_OPCODE_HANDLER_ARGS) int zend_unset_var_handler(ZEND_OPCODE_HANDLER_ARGS) { - zval tmp, *variable; + zval tmp, *varname; HashTable *target_symbol_table; - variable = get_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1), BP_VAR_R); + varname = get_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1), BP_VAR_R); - if (variable->type != IS_STRING) { - tmp = *variable; + if (varname->type != IS_STRING) { + tmp = *varname; zval_copy_ctor(&tmp); convert_to_string(&tmp); - variable = &tmp; + varname = &tmp; } - target_symbol_table = zend_get_target_symbol_table(EX(opline), EX(Ts), BP_VAR_IS, variable TSRMLS_CC); - - zend_hash_del(target_symbol_table, variable->value.str.val, variable->value.str.len+1); + if (EX(opline)->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) { + zend_std_unset_static_property(EX_T(EX(opline)->op2.u.var).EA.class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname) TSRMLS_CC); + } else { + target_symbol_table = zend_get_target_symbol_table(EX(opline), EX(Ts), BP_VAR_IS, varname TSRMLS_CC); + zend_hash_del(target_symbol_table, varname->value.str.val, varname->value.str.len+1); + } - if (variable == &tmp) { + if (varname == &tmp) { zval_dtor(&tmp); } FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1)); @@ -3643,22 +3646,28 @@ int zend_jmp_no_ctor_handler(ZEND_OPCODE_HANDLER_ARGS) int zend_isset_isempty_var_handler(ZEND_OPCODE_HANDLER_ARGS) { - zval tmp, *variable = get_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1), BP_VAR_R); + zval tmp, *varname = get_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1), BP_VAR_R); zval **value; zend_bool isset = 1; HashTable *target_symbol_table; - if (variable->type != IS_STRING) { - tmp = *variable; + if (varname->type != IS_STRING) { + tmp = *varname; zval_copy_ctor(&tmp); convert_to_string(&tmp); - variable = &tmp; + varname = &tmp; } - target_symbol_table = zend_get_target_symbol_table(EX(opline), EX(Ts), BP_VAR_IS, variable TSRMLS_CC); - - if (zend_hash_find(target_symbol_table, variable->value.str.val, variable->value.str.len+1, (void **) &value) == FAILURE) { - isset = 0; + if (EX(opline)->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) { + value = zend_std_get_static_property(EX_T(EX(opline)->op2.u.var).EA.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(EX(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; + } } EX_T(EX(opline)->result.u.var).tmp_var.type = IS_BOOL; @@ -3680,7 +3689,7 @@ int zend_isset_isempty_var_handler(ZEND_OPCODE_HANDLER_ARGS) break; } - if (variable == &tmp) { + if (varname == &tmp) { zval_dtor(&tmp); } FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1)); diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 071d246d85..aa3e75d1c8 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -592,7 +592,7 @@ static union _zend_function *zend_std_get_method(zval *object, char *method_name /* This is not (yet?) in the API, but it belongs in the built-in objects callbacks */ -zend_function *zend_get_static_method(zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC) +zend_function *zend_std_get_static_method(zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC) { zend_function *fbc; @@ -623,7 +623,7 @@ zend_function *zend_get_static_method(zend_class_entry *ce, char *function_name_ } -zval **zend_get_static_property(zend_class_entry *ce, char *property_name, int property_name_len, int type TSRMLS_DC) +zval **zend_std_get_static_property(zend_class_entry *ce, char *property_name, int property_name_len, zend_bool silent TSRMLS_DC) { HashTable *statics_table; zval **retval = NULL; @@ -631,64 +631,54 @@ zval **zend_get_static_property(zend_class_entry *ce, char *property_name, int p zend_property_info *property_info; zend_property_info std_property_info; - if(ce->type == ZEND_NAMESPACE) { + if (ce->type == ZEND_NAMESPACE) { zend_hash_find(ce->static_members, property_name, property_name_len+1, (void **) &retval); } else { - if (zend_hash_find(&ce->properties_info, property_name, property_name_len+1, (void **) &property_info)==FAILURE) { - std_property_info.flags = ZEND_ACC_PUBLIC; - std_property_info.name = property_name; - std_property_info.name_length = property_name_len; - std_property_info.h = zend_get_hash_value(std_property_info.name, std_property_info.name_length+1); - property_info = &std_property_info; - } + if (zend_hash_find(&ce->properties_info, property_name, property_name_len+1, (void **) &property_info)==FAILURE) { + std_property_info.flags = ZEND_ACC_PUBLIC; + std_property_info.name = property_name; + std_property_info.name_length = property_name_len; + std_property_info.h = zend_get_hash_value(std_property_info.name, std_property_info.name_length+1); + property_info = &std_property_info; + } #if 1&&DEBUG_OBJECT_HANDLERS - zend_printf("Access type for %s::%s is %s\n", ce->name, property_name, zend_visibility_string(property_info->flags)); + zend_printf("Access type for %s::%s is %s\n", ce->name, property_name, zend_visibility_string(property_info->flags)); #endif - if (!zend_verify_property_access(property_info, ce TSRMLS_CC)) { - zend_error(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ce->name, property_name); - } + if (!zend_verify_property_access(property_info, ce TSRMLS_CC)) { + zend_error(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ce->name, property_name); + } - while (tmp_ce) { - if (zend_hash_quick_find(tmp_ce->static_members, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval)==SUCCESS) { - statics_table = tmp_ce->static_members; - break; + while (tmp_ce) { + if (zend_hash_quick_find(tmp_ce->static_members, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval)==SUCCESS) { + statics_table = tmp_ce->static_members; + break; + } + tmp_ce = tmp_ce->parent; } - tmp_ce = tmp_ce->parent; - } } if (!retval) { - switch (type) { - case BP_VAR_R: - zend_error(E_NOTICE,"Undefined variable: %s::$%s", ce->name, property_name); - /* break missing intentionally */ - case BP_VAR_IS: - retval = &EG(uninitialized_zval_ptr); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined variable: %s::$%s", ce->name, property_name); - /* break missing intentionally */ - case BP_VAR_W: { - zval *new_zval = &EG(uninitialized_zval); - - if(ce->type != ZEND_NAMESPACE) { - new_zval->refcount++; - zend_hash_quick_update(ce->static_members, property_info->name, property_info->name_length+1, property_info->h, &new_zval, sizeof(zval *), (void **) &retval); - } - } - break; - EMPTY_SWITCH_DEFAULT_CASE() + if (silent) { + return NULL; + } else { + zend_error(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name, property_name); } - } else { - zval_update_constant(retval, (void *) 1 TSRMLS_CC); } - + + zval_update_constant(retval, (void *) 1 TSRMLS_CC); return retval; } +zend_bool zend_std_unset_static_property(zend_class_entry *ce, char *property_name, int property_name_len TSRMLS_DC) +{ + zend_error(E_ERROR, "Attempt to unset static property %s::$%s", ce->name, property_name); + return 0; +} + + static union _zend_function *zend_std_get_constructor(zval *object TSRMLS_DC) { zend_object *zobj = Z_OBJ_P(object); diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 442d92b72a..78c9e4fee3 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -93,8 +93,9 @@ typedef struct _zend_object_handlers { } zend_object_handlers; extern zend_object_handlers std_object_handlers; -union _zend_function *zend_get_static_method(zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC); -zval **zend_get_static_property(zend_class_entry *ce, char *property_name, int property_name_len, int type TSRMLS_DC); +union _zend_function *zend_std_get_static_method(zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC); +zval **zend_std_get_static_property(zend_class_entry *ce, char *property_name, int property_name_len, zend_bool silent TSRMLS_DC); +zend_bool zend_std_unset_static_property(zend_class_entry *ce, char *property_name, int property_name_len TSRMLS_DC); #define IS_ZEND_STD_OBJECT(z) ((z).type == IS_OBJECT && (Z_OBJ_HT((z))->get_class_entry != NULL))