summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndi Gutmans <andi@php.net>2002-02-21 11:50:44 +0000
committerAndi Gutmans <andi@php.net>2002-02-21 11:50:44 +0000
commit00e90f2ff3053a0cca50514bd17a036af5b5dac5 (patch)
tree46d7374f8d267b63e2dbc468e7aa81e29ddce957
parent15daf9928819f213c331c8fd6fe4412be703b8bd (diff)
downloadphp-git-00e90f2ff3053a0cca50514bd17a036af5b5dac5.tar.gz
- Experimental support for private members.
<? class MyClass { private $Hello = "Hello, World!\n"; function printHello() { print $this->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(); ?>
-rw-r--r--Zend/zend.c1
-rw-r--r--Zend/zend.h1
-rw-r--r--Zend/zend_API.c1
-rw-r--r--Zend/zend_compile.c41
-rw-r--r--Zend/zend_language_parser.y2
-rw-r--r--Zend/zend_language_scanner.l4
-rw-r--r--Zend/zend_object_handlers.c2
-rw-r--r--Zend/zend_opcode.c2
8 files changed, 53 insertions, 1 deletions
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;
}
+<ST_IN_SCRIPTING>"private" {
+ return T_PRIVATE;
+}
+
<ST_IN_SCRIPTING>"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);