]> granicus.if.org Git - php/commitdiff
Improve handling of static member variables
authorZeev Suraski <zeev@php.net>
Mon, 17 Feb 2003 14:06:39 +0000 (14:06 +0000)
committerZeev Suraski <zeev@php.net>
Mon, 17 Feb 2003 14:06:39 +0000 (14:06 +0000)
Zend/zend_execute.c
Zend/zend_object_handlers.c
Zend/zend_object_handlers.h

index 3f1c52e82bc2362e52f50797027b587a41371dfc..961a52fd93e4966b387cab35674f4f1587c3bb15 100644 (file)
@@ -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));
index 071d246d8508d70e4fb359a5b124c7bdb65414ac..aa3e75d1c8b5a1ebbacc8592c003397bb46d2b0c 100644 (file)
@@ -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);
index 442d92b72a6814d95a162c3a92d644c10032a4db..78c9e4fee3c4922ddfe62a9f6d0a1fe8ee6e306e 100644 (file)
@@ -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))