From d2da63f629632c8d7940566a71be66c952b17583 Mon Sep 17 00:00:00 2001 From: Andi Gutmans Date: Sun, 25 Nov 2001 08:49:09 +0000 Subject: [PATCH] - Support static members. The following script works: --- Zend/zend.c | 1 + Zend/zend.h | 1 + Zend/zend_API.c | 2 ++ Zend/zend_compile.c | 20 ++++++++++++++++++++ Zend/zend_compile.h | 8 +++++--- Zend/zend_execute.c | 5 ++++- Zend/zend_language_parser.y | 10 +++++++++- Zend/zend_opcode.c | 2 ++ 8 files changed, 44 insertions(+), 5 deletions(-) diff --git a/Zend/zend.c b/Zend/zend.c index a1563cd0fa..e7987873fc 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -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; diff --git a/Zend/zend.h b/Zend/zend.h index 095254fe0b..924f541091 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -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; diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 9eecbdb597..670e2e3c1f 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -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); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 184d56067e..5e9cc6bc0d 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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 */ diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 9912ce8c4f..e133a01941 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -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 diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index bb80793a28..77f39bd0aa 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -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); } diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 8a3b437ddb..e772889bb6 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -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); } diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 273a4b3762..6d16b719b3 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -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; } -- 2.40.0