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;
HashTable function_table;
HashTable default_properties;
HashTable class_table;
+ HashTable static_members;
zend_function_entry *builtin_functions;
union _zend_function *constructor;
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;
}
*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);
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)
{
/* 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)
(*ce->refcount)--;
zend_hash_destroy(&ce->function_table);
zend_hash_destroy(&ce->default_properties);
+ zend_hash_destroy(&ce->static_members);
return FAILURE;
}
return SUCCESS;
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;
/* 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 */
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 *);
/* 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
}
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()
}
}
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);
}
static_or_variable_string:
T_STRING { $$ = $1; }
- | r_cvar { $$ = $1; }
+ | r_cvar_without_static_member { $$ = $1; }
;
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); }
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:
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;
}