]> granicus.if.org Git - php/commitdiff
- Support static members. The following script works:
authorAndi Gutmans <andi@php.net>
Sun, 25 Nov 2001 08:49:09 +0000 (08:49 +0000)
committerAndi Gutmans <andi@php.net>
Sun, 25 Nov 2001 08:49:09 +0000 (08:49 +0000)
<?
class foo
{
class bar
{
function init_values()
{
for ($i=1; $i<10; $i++) {
foo::bar::$hello[$i] = $i*$i;
}
}

function print_values()
{
for ($i=1; $i<10; $i++) {
print foo::bar::$hello[$i] . "\n";
}
}
}
}

foo::bar::init_values();
foo::bar::print_values();

for ($i=1; $i<10; $i++) {
print $hello[$i]?"Shouldn't be printed\n":"";
}
?>

Zend/zend.c
Zend/zend.h
Zend/zend_API.c
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute.c
Zend/zend_language_parser.y
Zend/zend_opcode.c

index a1563cd0fa67384236516e0401c832e3cf760594..e7987873fc6539b25a7872c64c61e7bbaa09681d 100644 (file)
@@ -251,6 +251,7 @@ static void register_standard_class(void)
        zend_standard_class_def.name = zend_strndup("stdClass", zend_standard_class_def.name_length);
        zend_standard_class_def.parent = NULL;
        zend_hash_init_ex(&zend_standard_class_def.default_properties, 0, NULL, ZVAL_PTR_DTOR, 1, 0);
+       zend_hash_init_ex(&zend_standard_class_def.static_members, 0, NULL, ZVAL_PTR_DTOR, 1, 0);
        zend_hash_init_ex(&zend_standard_class_def.function_table, 0, NULL, ZEND_FUNCTION_DTOR, 1, 0);
        zend_standard_class_def.constructor = NULL;
        zend_standard_class_def.handle_function_call = NULL;
index 095254fe0beda5b94852aeb6e7833a1174d4279a..924f5410911627baa293bad43284dce1bb2763a0 100644 (file)
@@ -284,6 +284,7 @@ struct _zend_class_entry {
        HashTable function_table;
        HashTable default_properties;
        HashTable class_table;
+       HashTable static_members;
        zend_function_entry *builtin_functions;
 
        union _zend_function *constructor;
index 9eecbdb597b7df34f18256f10336e81b1fcd14d5..670e2e3c1ff185d4f09c88e3e1c349719688af18 100644 (file)
@@ -572,6 +572,7 @@ ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type
 
        if (!class_type->constants_updated) {
                zend_hash_apply_with_argument(&class_type->default_properties, (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC);
+               zend_hash_apply_with_argument(&class_type->static_members, (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC);
                class_type->constants_updated = 1;
        }
        
@@ -1215,6 +1216,7 @@ ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *class_
        *class_entry->refcount = 1;
        class_entry->constants_updated = 0;
        zend_hash_init(&class_entry->default_properties, 0, NULL, ZVAL_PTR_DTOR, 1);
+       zend_hash_init(&class_entry->static_members, 0, NULL, ZVAL_PTR_DTOR, 1);
        zend_hash_init(&class_entry->function_table, 0, NULL, ZEND_FUNCTION_DTOR, 1);
        zend_hash_init(&class_entry->class_table, 10, NULL, ZEND_CLASS_DTOR, 1);
 
index 184d56067e2b830017337287f4078ba6b82caa4e..5e9cc6bc0d30cc1e740e6b56efcac2b148007bd5 100644 (file)
@@ -254,6 +254,19 @@ void fetch_simple_variable(znode *result, znode *varname, int bp TSRMLS_DC)
        fetch_simple_variable_ex(result, varname, bp, ZEND_FETCH_W TSRMLS_CC);
 }
 
+void zend_do_fetch_static_member(znode *class  TSRMLS_DC)
+{
+       zend_llist *fetch_list_ptr;
+       zend_llist_element *le;
+       zend_op *opline_ptr;
+
+       zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
+       le = fetch_list_ptr->head;
+
+       opline_ptr = (zend_op *)le->data;
+       opline_ptr->op2 = *class;
+       opline_ptr->extended_value = ZEND_FETCH_STATIC_MEMBER;
+}
 
 void fetch_array_begin(znode *result, znode *varname, znode *first_dim TSRMLS_DC)
 {
@@ -1251,6 +1264,8 @@ void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce)
 
        /* Perform inheritance */
        zend_hash_merge(&ce->default_properties, &parent_ce->default_properties, (void (*)(void *)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0);
+       /* STATIC_MEMBERS_FIXME */
+       zend_hash_merge(&ce->static_members, &parent_ce->static_members, (void (*)(void *)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0);
        zend_hash_merge(&ce->function_table, &parent_ce->function_table, (void (*)(void *)) function_add_ref, &tmp_zend_function, sizeof(zend_function), 0);
        ce->parent = parent_ce;
        if (!ce->handle_property_get)
@@ -1357,6 +1372,7 @@ ZEND_API int do_bind_function_or_class(zend_op *opline, HashTable *function_tabl
                                        (*ce->refcount)--;
                                        zend_hash_destroy(&ce->function_table);
                                        zend_hash_destroy(&ce->default_properties);
+                                       zend_hash_destroy(&ce->static_members);
                                        return FAILURE;
                                }
                                return SUCCESS;
@@ -1688,6 +1704,7 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod
        zend_hash_init(&new_class_entry.function_table, 10, NULL, ZEND_FUNCTION_DTOR, 0);
        zend_hash_init(&new_class_entry.class_table, 10, NULL, ZEND_CLASS_DTOR, 0);
        zend_hash_init(&new_class_entry.default_properties, 10, NULL, ZVAL_PTR_DTOR, 0);
+       zend_hash_init(&new_class_entry.static_members, 10, NULL, ZVAL_PTR_DTOR, 0);
 
        new_class_entry.constructor = NULL;
 
@@ -1712,6 +1729,9 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod
                        /* copy default properties */
                        zend_hash_copy(&new_class_entry.default_properties, &parent_class->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
 
+                       /* copy static members */
+                       zend_hash_copy(&new_class_entry.static_members, &parent_class->static_members, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
+
                        new_class_entry.constructor = parent_class->constructor;
 
                        /* copy overloaded handlers */
index 9912ce8c4f2ec38598225b03ecda5b5fc7d5072d..e133a01941697e64c6300fc0666938396dd42564 100644 (file)
@@ -232,6 +232,7 @@ void zend_do_fetch_globals(znode *varname TSRMLS_DC);
 void fetch_array_begin(znode *result, znode *varname, znode *first_dim TSRMLS_DC);
 void fetch_array_dim(znode *result, znode *parent, znode *dim TSRMLS_DC);
 void fetch_string_offset(znode *result, znode *parent, znode *offset TSRMLS_DC);
+void zend_do_fetch_static_member(znode *class TSRMLS_DC);
 void zend_do_print(znode *result, znode *arg TSRMLS_DC);
 void zend_do_echo(znode *arg TSRMLS_DC);
 typedef int (*unary_op_type)(zval *, zval *);
@@ -544,9 +545,10 @@ int zendlex(znode *zendlval TSRMLS_DC);
 
 
 /* global/local fetches */
-#define ZEND_FETCH_GLOBAL      0
-#define ZEND_FETCH_LOCAL       1
-#define ZEND_FETCH_STATIC      2
+#define ZEND_FETCH_GLOBAL                      0
+#define ZEND_FETCH_LOCAL                       1
+#define ZEND_FETCH_STATIC                      2
+#define ZEND_FETCH_STATIC_MEMBER       3
 
 /* unset types */
 #define ZEND_UNSET_REG 0
index bb80793a280c913765506ddcef409650d212022c..77f39bd0aa91342cf291838ef28ae5e26248b3fd 100644 (file)
@@ -547,6 +547,9 @@ static void zend_fetch_var_address(zend_op *opline, temp_variable *Ts, int type
                        }
                        target_symbol_table = EG(active_op_array)->static_variables;
                        break;
+               case ZEND_FETCH_STATIC_MEMBER:
+                       target_symbol_table = &Ts[opline->op2.u.var].EA.class_entry->static_members;
+                       break;
                EMPTY_SWITCH_DEFAULT_CASE()
        }
 
@@ -579,7 +582,7 @@ static void zend_fetch_var_address(zend_op *opline, temp_variable *Ts, int type
        }
        if (opline->extended_value == ZEND_FETCH_LOCAL) {
                FREE_OP(Ts, &opline->op1, free_op1);
-       } else if (opline->extended_value == ZEND_FETCH_STATIC) {
+       } else if (opline->extended_value == ZEND_FETCH_STATIC || opline->extended_value == ZEND_FETCH_STATIC_MEMBER) {
                zval_update_constant(retval, (void *) 1 TSRMLS_CC);
        }
 
index 8a3b437ddb45bf796a65925382d251610129b7fc..e772889bb6c4b41203c47edb67c02f4aad240b31 100644 (file)
@@ -515,7 +515,7 @@ parse_class_entry:
 
 static_or_variable_string:
                T_STRING        { $$ = $1; }
-       |       r_cvar          { $$ = $1; }
+       |       r_cvar_without_static_member    { $$ = $1; }
 ;
 
 
@@ -597,10 +597,18 @@ rw_cvar:
        cvar { zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC); $$ = $1; }
 ;
 
+r_cvar_without_static_member:
+       variable { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); $$ = $1; }
+;
+
 cvar:
                variable { $$ = $1; }
+       |       static_member {$$ = $1; }
 ;
 
+static_member:
+       parse_class_entry T_PAAMAYIM_NEKUDOTAYIM variable { $$ = $3; zend_do_fetch_static_member(&$1 TSRMLS_CC); }
+;
 
 variable:
                variable_property '(' { zend_do_begin_method_call(NULL, &$1 TSRMLS_CC); }
index 273a4b3762e1d2cea0556bbd7008aa933eeb50b5..6d16b719b38e2d5ce8bd650b687de57eaafce43f 100644 (file)
@@ -117,6 +117,7 @@ ZEND_API void destroy_zend_class(zend_class_entry *ce)
                        efree(ce->refcount);
                        zend_hash_destroy(&ce->function_table);
                        zend_hash_destroy(&ce->default_properties);
+                       zend_hash_destroy(&ce->static_members);
                        zend_hash_destroy(&ce->class_table);
                        break;
                case ZEND_INTERNAL_CLASS:
@@ -124,6 +125,7 @@ ZEND_API void destroy_zend_class(zend_class_entry *ce)
                        free(ce->refcount);
                        zend_hash_destroy(&ce->function_table);
                        zend_hash_destroy(&ce->default_properties);
+                       zend_hash_destroy(&ce->static_members);
                        zend_hash_destroy(&ce->class_table);
                        break;
        }