summaryrefslogtreecommitdiff
path: root/Zend/zend_execute.c
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2002-10-16 18:29:41 +0000
committerStanislav Malyshev <stas@php.net>2002-10-16 18:29:41 +0000
commitc42ec35331a853d2a1b11700088eef31fc1f907f (patch)
treec12e6903ddb5718af0bd456f3ad986601276cabd /Zend/zend_execute.c
parent349b3a096aa677b8ee3977a965b42c187b6a5bc5 (diff)
downloadphp-git-c42ec35331a853d2a1b11700088eef31fc1f907f.tar.gz
Fix class static members: now the following code works:
<?php class Foo { static $c = "Parent"; } class Child extends Foo { } Foo::$c = "Hello"; var_dump(Child::$c); ?> and returns "Hello" (class statics are not copied anymore, but looked up in runtime)
Diffstat (limited to 'Zend/zend_execute.c')
-rw-r--r--Zend/zend_execute.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index b93c4cfefe..d971cb655a 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -612,7 +612,20 @@ static void print_refcount(zval *p, char *str)
print_refcount(NULL, NULL);
}
-static inline HashTable *zend_get_target_symbol_table(zend_op *opline, temp_variable *Ts, int type TSRMLS_DC)
+static inline HashTable *zend_find_inherited_static(zend_class_entry *ce, zval *variable)
+{
+ zend_class_entry *orig_ce = ce;
+
+ while (ce) {
+ if (zend_hash_exists(ce->static_members, Z_STRVAL_P(variable), Z_STRLEN_P(variable)+1)) {
+ return ce->static_members;
+ }
+ ce = ce->parent;
+ }
+ return orig_ce->static_members;
+}
+
+static inline HashTable *zend_get_target_symbol_table(zend_op *opline, temp_variable *Ts, int type, zval *variable TSRMLS_DC)
{
switch (opline->op2.u.EA.type) {
case ZEND_FETCH_LOCAL:
@@ -634,7 +647,13 @@ static inline HashTable *zend_get_target_symbol_table(zend_op *opline, temp_vari
return EG(active_op_array)->static_variables;
break;
case ZEND_FETCH_STATIC_MEMBER:
- return Ts[opline->op2.u.var].EA.class_entry->static_members;
+ if(Ts[opline->op2.u.var].EA.class_entry->parent) {
+ /* if inherited, try to look up */
+ return zend_find_inherited_static(Ts[opline->op2.u.var].EA.class_entry, variable);
+ } else {
+ /* if class is not inherited, no point in checking */
+ return Ts[opline->op2.u.var].EA.class_entry->static_members;
+ }
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
@@ -650,11 +669,6 @@ static void zend_fetch_var_address(zend_op *opline, temp_variable *Ts, int type
zval tmp_varname;
HashTable *target_symbol_table;
- target_symbol_table = zend_get_target_symbol_table(opline, Ts, type TSRMLS_CC);
- if (!target_symbol_table) {
- return;
- }
-
if (varname->type != IS_STRING) {
tmp_varname = *varname;
zval_copy_ctor(&tmp_varname);
@@ -662,6 +676,11 @@ static void zend_fetch_var_address(zend_op *opline, temp_variable *Ts, int type
varname = &tmp_varname;
}
+ target_symbol_table = zend_get_target_symbol_table(opline, Ts, type, varname TSRMLS_CC);
+ if (!target_symbol_table) {
+ return;
+ }
+
if (zend_hash_find(target_symbol_table, varname->value.str.val, varname->value.str.len+1, (void **) &retval) == FAILURE) {
switch (type) {
case BP_VAR_R:
@@ -2811,7 +2830,6 @@ send_by_ref:
HashTable *target_symbol_table;
variable = get_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
- target_symbol_table = zend_get_target_symbol_table(EX(opline), EX(Ts), BP_VAR_IS TSRMLS_CC);
if (variable->type != IS_STRING) {
tmp = *variable;
@@ -2820,6 +2838,8 @@ send_by_ref:
variable = &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 (variable == &tmp) {
@@ -2987,8 +3007,6 @@ send_by_ref:
zend_bool isset = 1;
HashTable *target_symbol_table;
- target_symbol_table = zend_get_target_symbol_table(EX(opline), EX(Ts), BP_VAR_IS TSRMLS_CC);
-
if (variable->type != IS_STRING) {
tmp = *variable;
zval_copy_ctor(&tmp);
@@ -2996,6 +3014,8 @@ send_by_ref:
variable = &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;
}