Skip to content
Browse files

- Support static members. The following script works:

<?
	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":"";
	}
?>
  • Loading branch information...
1 parent 3d741d7 commit d2da63f629632c8d7940566a71be66c952b17583 @andigutmans andigutmans committed Nov 25, 2001
Showing with 44 additions and 5 deletions.
  1. +1 −0 Zend/zend.c
  2. +1 −0 Zend/zend.h
  3. +2 −0 Zend/zend_API.c
  4. +20 −0 Zend/zend_compile.c
  5. +5 −3 Zend/zend_compile.h
  6. +4 −1 Zend/zend_execute.c
  7. +9 −1 Zend/zend_language_parser.y
  8. +2 −0 Zend/zend_opcode.c
View
1 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;
View
1 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;
View
2 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);
View
20 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 */
View
8 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
View
5 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);
}
View
10 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); }
View
2 Zend/zend_opcode.c
@@ -117,13 +117,15 @@ 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:
free(ce->name);
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;
}

0 comments on commit d2da63f

Please sign in to comment.
Something went wrong with that request. Please try again.