From: Andi Gutmans Date: Thu, 21 Feb 2002 11:50:44 +0000 (+0000) Subject: - Experimental support for private members. X-Git-Tag: php-4.2.0RC1~302 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=00e90f2ff3053a0cca50514bd17a036af5b5dac5;p=php - Experimental support for private members. Hello; } } class MyClass2 extends MyClass { function printHello() { MyClass::printHello(); /* Should print */ print $this->Hello; /* Shouldn't print out anything */ } } $obj = new MyClass(); print $obj->Hello; /* Shouldn't print out anything */ $obj->printHello(); /* Should print */ $obj = new MyClass2(); print $obj->Hello; /* Shouldn't print out anything */ $obj->printHello(); ?> --- diff --git a/Zend/zend.c b/Zend/zend.c index ecbb4d828b..67f498bd79 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.private_properties, 0, NULL, ZVAL_PTR_DTOR, 1, 0); zend_standard_class_def.static_members = (HashTable *) malloc(sizeof(HashTable)); 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.constants_table, 0, NULL, ZVAL_PTR_DTOR, 1, 0); diff --git a/Zend/zend.h b/Zend/zend.h index 9791075d68..98501df6ca 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -270,6 +270,7 @@ struct _zend_class_entry { HashTable function_table; HashTable default_properties; + HashTable private_properties; /* This is only needed at compile-time */ HashTable class_table; HashTable *static_members; HashTable constants_table; diff --git a/Zend/zend_API.c b/Zend/zend_API.c index f6121a8cd3..7e03e22d4f 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1224,6 +1224,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->private_properties, 0, NULL, ZVAL_PTR_DTOR, 1); class_entry->static_members = (HashTable *) malloc(sizeof(HashTable)); zend_hash_init(class_entry->static_members, 0, NULL, ZVAL_PTR_DTOR, 1); zend_hash_init(&class_entry->constants_table, 0, NULL, ZVAL_PTR_DTOR, 1); diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 143ca3589e..96a92b7356 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1366,6 +1366,7 @@ static void create_class(HashTable *class_table, char *name, int name_length, ze 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.private_properties, 10, NULL, ZVAL_PTR_DTOR, 0); ALLOC_HASHTABLE(new_class_entry.static_members); zend_hash_init(new_class_entry.static_members, 10, NULL, ZVAL_PTR_DTOR, 0); zend_hash_init(&new_class_entry.constants_table, 10, NULL, ZVAL_PTR_DTOR, 0); @@ -1520,6 +1521,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->private_properties); zend_hash_destroy(ce->static_members); zend_hash_destroy(&ce->constants_table); return FAILURE; @@ -1856,6 +1858,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.private_properties, 10, NULL, ZVAL_PTR_DTOR, 0); ALLOC_HASHTABLE(new_class_entry.static_members); zend_hash_init(new_class_entry.static_members, 10, NULL, ZVAL_PTR_DTOR, 0); zend_hash_init(&new_class_entry.constants_table, 10, NULL, ZVAL_PTR_DTOR, 0); @@ -1963,6 +1966,20 @@ void zend_do_end_class_declaration(znode *class_token TSRMLS_DC) } } +void mangle_private_property_name(char **dest, int *dest_length, char *src1, int src1_length, char *src2, int src2_length) +{ + char *priv_name; + int priv_name_length; + + priv_name_length = 1 + src1_length + 1 + src2_length; + priv_name = emalloc(priv_name_length+1); + priv_name[0] = '\0'; + memcpy(priv_name + 1, src1, src1_length+1); + memcpy(priv_name + 1 + src1_length + 1, src2, src2_length+1); + + *dest = priv_name; + *dest_length = priv_name_length; +} void zend_do_declare_property(znode *var_name, znode *value, int declaration_type TSRMLS_DC) { @@ -1978,6 +1995,19 @@ void zend_do_declare_property(znode *var_name, znode *value, int declaration_typ } switch (declaration_type) { + case T_PRIVATE: + { + char *priv_name; + int priv_name_length; + + mangle_private_property_name(&priv_name, &priv_name_length, CG(active_class_entry)->name, CG(active_class_entry)->name_length, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len); + zend_hash_update(&CG(active_class_entry)->default_properties, priv_name, priv_name_length+1, &property, sizeof(zval *), NULL); + efree(priv_name); + + property->refcount++; + zend_hash_update(&CG(active_class_entry)->private_properties, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, &property, sizeof(zval *), NULL); + break; + } case T_VAR: zend_hash_update(&CG(active_class_entry)->default_properties, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, &property, sizeof(zval *), NULL); break; @@ -2010,6 +2040,17 @@ void zend_do_fetch_property(znode *result, znode *object, znode *property TSRMLS SET_UNUSED(opline_ptr->op2); opline_ptr->op2.u.EA.type = ZEND_FETCH_FROM_THIS; + if ((opline_ptr->op1.op_type == IS_CONST) && zend_hash_exists(&CG(active_class_entry)->private_properties, opline_ptr->op1.u.constant.value.str.val, opline_ptr->op1.u.constant.value.str.len+1)) { + char *priv_name; + int priv_name_length; + + mangle_private_property_name(&priv_name, &priv_name_length, CG(active_class_entry)->name, CG(active_class_entry)->name_length, opline_ptr->op1.u.constant.value.str.val, opline_ptr->op1.u.constant.value.str.len); + + STR_FREE(opline_ptr->op1.u.constant.value.str.val); + opline_ptr->op1.u.constant.value.str.val = priv_name; + opline_ptr->op1.u.constant.value.str.len = priv_name_length; + } + *result = opline_ptr->result; return; } diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 30f04d874a..8975871f37 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -111,6 +111,7 @@ %token T_USE %token T_GLOBAL %token T_STATIC +%token T_PRIVATE %token T_VAR %token T_UNSET %token T_ISSET @@ -421,6 +422,7 @@ class_variable_decleration: class_decleration_type: T_VAR { $$.op_type = T_VAR; } | T_STATIC { $$.op_type = T_STATIC; } + | T_PRIVATE { $$.op_type = T_PRIVATE; } ; class_constant_decleration: diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 528d8cfdb0..2a615ff27b 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -705,6 +705,10 @@ NEWLINE ("\r"|"\n"|"\r\n") return T_STATIC; } +"private" { + return T_PRIVATE; +} + "unset" { return T_UNSET; } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 44d2526326..9db2cbce5a 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -5,7 +5,7 @@ #include "zend_objects.h" #include "zend_object_handlers.h" -#define DEBUG_OBJECT_HANDLERS 1 +#define DEBUG_OBJECT_HANDLERS 0 static HashTable *zend_std_get_properties(zval *object TSRMLS_DC) { diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 85e5904b11..d995065119 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -112,6 +112,7 @@ ZEND_API void destroy_zend_class(zend_class_entry *ce) switch (ce->type) { case ZEND_USER_CLASS: zend_hash_destroy(&ce->default_properties); + zend_hash_destroy(&ce->private_properties); zend_hash_destroy(ce->static_members); efree(ce->name); efree(ce->refcount); @@ -122,6 +123,7 @@ ZEND_API void destroy_zend_class(zend_class_entry *ce) break; case ZEND_INTERNAL_CLASS: zend_hash_destroy(&ce->default_properties); + zend_hash_destroy(&ce->private_properties); zend_hash_destroy(ce->static_members); free(ce->name); free(ce->refcount);