mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
- Make classes have scope and function/constant lookups default to the class
This commit is contained in:
parent
657ce39a28
commit
74efc41fc3
7 changed files with 31 additions and 38 deletions
11
Zend/zend.h
11
Zend/zend.h
|
@ -183,16 +183,6 @@ typedef unsigned short zend_ushort;
|
||||||
#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval *this_ptr, int return_value_used TSRMLS_DC
|
#define INTERNAL_FUNCTION_PARAMETERS int ht, zval *return_value, zval *this_ptr, int return_value_used TSRMLS_DC
|
||||||
#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, this_ptr, return_value_used TSRMLS_CC
|
#define INTERNAL_FUNCTION_PARAM_PASSTHRU ht, return_value, this_ptr, return_value_used TSRMLS_CC
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
INTERNAL_NAMESPACE = 0,
|
|
||||||
USER_NAMESPACE = 1
|
|
||||||
} namespace_type;
|
|
||||||
|
|
||||||
typedef struct _zend_namespace_struct {
|
|
||||||
namespace_type type;
|
|
||||||
HashTable *class_table;
|
|
||||||
HashTable *function_table;
|
|
||||||
} zend_namespace;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* zval
|
* zval
|
||||||
|
@ -292,7 +282,6 @@ struct _zend_class_entry {
|
||||||
struct _zend_class_entry *parent;
|
struct _zend_class_entry *parent;
|
||||||
int *refcount;
|
int *refcount;
|
||||||
zend_bool constants_updated;
|
zend_bool constants_updated;
|
||||||
zend_bool is_namespace;
|
|
||||||
|
|
||||||
HashTable function_table;
|
HashTable function_table;
|
||||||
HashTable default_properties;
|
HashTable default_properties;
|
||||||
|
|
|
@ -1215,7 +1215,6 @@ ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *class_
|
||||||
class_entry->refcount = (int *) malloc(sizeof(int));
|
class_entry->refcount = (int *) malloc(sizeof(int));
|
||||||
*class_entry->refcount = 1;
|
*class_entry->refcount = 1;
|
||||||
class_entry->constants_updated = 0;
|
class_entry->constants_updated = 0;
|
||||||
class_entry->is_namespace = 0;
|
|
||||||
zend_hash_init(&class_entry->default_properties, 0, NULL, ZVAL_PTR_DTOR, 1);
|
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->static_members, 0, NULL, ZVAL_PTR_DTOR, 1);
|
||||||
zend_hash_init(&class_entry->constants_table, 0, NULL, ZVAL_PTR_DTOR, 1);
|
zend_hash_init(&class_entry->constants_table, 0, NULL, ZVAL_PTR_DTOR, 1);
|
||||||
|
|
|
@ -82,8 +82,6 @@ void zend_init_compiler_data_structures(TSRMLS_D)
|
||||||
CG(in_compilation) = 0;
|
CG(in_compilation) = 0;
|
||||||
init_compiler_declarables(TSRMLS_C);
|
init_compiler_declarables(TSRMLS_C);
|
||||||
CG(throw_list) = NULL;
|
CG(throw_list) = NULL;
|
||||||
CG(namespace) = NULL;
|
|
||||||
CG(namespace_len) = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -108,10 +106,6 @@ void shutdown_compiler(TSRMLS_D)
|
||||||
zend_stack_destroy(&CG(list_stack));
|
zend_stack_destroy(&CG(list_stack));
|
||||||
zend_hash_destroy(&CG(filenames_table));
|
zend_hash_destroy(&CG(filenames_table));
|
||||||
zend_llist_destroy(&CG(open_files));
|
zend_llist_destroy(&CG(open_files));
|
||||||
|
|
||||||
if (CG(namespace)) {
|
|
||||||
efree(CG(namespace));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -928,7 +922,14 @@ void do_fetch_class(znode *result, znode *class_entry, znode *class_name TSRMLS_
|
||||||
SET_UNUSED(opline->op1);
|
SET_UNUSED(opline->op1);
|
||||||
}
|
}
|
||||||
zend_str_tolower(class_name->u.constant.value.str.val, class_name->u.constant.value.str.len);
|
zend_str_tolower(class_name->u.constant.value.str.val, class_name->u.constant.value.str.len);
|
||||||
opline->op2 = *class_name;
|
if ((class_name->u.constant.value.str.len == (sizeof("self") - 1)) &&
|
||||||
|
!memcmp(class_name->u.constant.value.str.val, "self", sizeof("self"))) {
|
||||||
|
SET_UNUSED(opline->op2);
|
||||||
|
opline->extended_value = ZEND_FETCH_CLASS_SELF;
|
||||||
|
zval_dtor(&class_name->u.constant);
|
||||||
|
} else {
|
||||||
|
opline->op2 = *class_name;
|
||||||
|
}
|
||||||
opline->result.u.var = get_temporary_variable(CG(active_op_array));
|
opline->result.u.var = get_temporary_variable(CG(active_op_array));
|
||||||
opline->result.op_type = IS_CONST; /* FIXME: Hack so that INIT_FCALL_BY_NAME still knows this is a class */
|
opline->result.op_type = IS_CONST; /* FIXME: Hack so that INIT_FCALL_BY_NAME still knows this is a class */
|
||||||
*result = opline->result;
|
*result = opline->result;
|
||||||
|
@ -1702,7 +1703,7 @@ void zend_do_default_before_statement(znode *case_list, znode *default_token TSR
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znode *parent_class_name, zend_bool is_namespace TSRMLS_DC)
|
void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znode *parent_class_name TSRMLS_DC)
|
||||||
{
|
{
|
||||||
zend_op *opline;
|
zend_op *opline;
|
||||||
int runtime_inheritance = 0;
|
int runtime_inheritance = 0;
|
||||||
|
@ -1715,7 +1716,6 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod
|
||||||
new_class_entry.refcount = (int *) emalloc(sizeof(int));
|
new_class_entry.refcount = (int *) emalloc(sizeof(int));
|
||||||
*new_class_entry.refcount = 1;
|
*new_class_entry.refcount = 1;
|
||||||
new_class_entry.constants_updated = 0;
|
new_class_entry.constants_updated = 0;
|
||||||
new_class_entry.is_namespace = is_namespace;
|
|
||||||
|
|
||||||
zend_str_tolower(new_class_entry.name, new_class_entry.name_length);
|
zend_str_tolower(new_class_entry.name, new_class_entry.name_length);
|
||||||
|
|
||||||
|
|
|
@ -303,7 +303,7 @@ void zend_do_case_before_statement(znode *case_list, znode *case_token, znode *c
|
||||||
void zend_do_case_after_statement(znode *result, znode *case_token TSRMLS_DC);
|
void zend_do_case_after_statement(znode *result, znode *case_token TSRMLS_DC);
|
||||||
void zend_do_default_before_statement(znode *case_list, znode *default_token TSRMLS_DC);
|
void zend_do_default_before_statement(znode *case_list, znode *default_token TSRMLS_DC);
|
||||||
|
|
||||||
void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znode *parent_class_name, zend_bool is_namespace TSRMLS_DC);
|
void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znode *parent_class_name TSRMLS_DC);
|
||||||
void zend_do_end_class_declaration(znode *class_token TSRMLS_DC);
|
void zend_do_end_class_declaration(znode *class_token TSRMLS_DC);
|
||||||
void zend_do_declare_property(znode *var_name, znode *value, int declaration_type TSRMLS_DC);
|
void zend_do_declare_property(znode *var_name, znode *value, int declaration_type TSRMLS_DC);
|
||||||
|
|
||||||
|
@ -551,6 +551,10 @@ int zendlex(znode *zendlval TSRMLS_DC);
|
||||||
#define ZEND_FETCH_STATIC 2
|
#define ZEND_FETCH_STATIC 2
|
||||||
#define ZEND_FETCH_STATIC_MEMBER 3
|
#define ZEND_FETCH_STATIC_MEMBER 3
|
||||||
|
|
||||||
|
/* class fetches */
|
||||||
|
#define ZEND_FETCH_CLASS_DEFAULT 0
|
||||||
|
#define ZEND_FETCH_CLASS_SELF 1
|
||||||
|
|
||||||
/* unset types */
|
/* unset types */
|
||||||
#define ZEND_UNSET_REG 0
|
#define ZEND_UNSET_REG 0
|
||||||
#define ZEND_UNSET_OBJ 1
|
#define ZEND_UNSET_OBJ 1
|
||||||
|
|
|
@ -1492,7 +1492,17 @@ binary_assign_op_addr: {
|
||||||
{
|
{
|
||||||
if (EX(opline)->op1.op_type == IS_UNUSED) {
|
if (EX(opline)->op1.op_type == IS_UNUSED) {
|
||||||
zval tmp;
|
zval tmp;
|
||||||
zval *class_name = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
|
zval *class_name;
|
||||||
|
|
||||||
|
if (EX(opline)->extended_value == ZEND_FETCH_CLASS_SELF) {
|
||||||
|
if (!EG(namespace)) {
|
||||||
|
zend_error(E_ERROR, "Cannot fetch self:: when no class scope is active");
|
||||||
|
}
|
||||||
|
EX(Ts)[EX(opline)->result.u.var].EA.class_entry = EG(namespace);
|
||||||
|
NEXT_OPCODE();
|
||||||
|
}
|
||||||
|
|
||||||
|
class_name = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
|
||||||
|
|
||||||
if (class_name->type != IS_STRING) {
|
if (class_name->type != IS_STRING) {
|
||||||
tmp = *class_name;
|
tmp = *class_name;
|
||||||
|
@ -1570,9 +1580,7 @@ binary_assign_op_addr: {
|
||||||
{
|
{
|
||||||
zend_class_entry *ce = EX(Ts)[EX(opline)->op1.u.var].EA.class_entry;
|
zend_class_entry *ce = EX(Ts)[EX(opline)->op1.u.var].EA.class_entry;
|
||||||
active_function_table = &ce->function_table;
|
active_function_table = &ce->function_table;
|
||||||
if (ce->is_namespace) {
|
EX(calling_namespace) = ce;
|
||||||
EX(calling_namespace) = ce;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else { /* used for member function calls */
|
} else { /* used for member function calls */
|
||||||
EX(object).ptr = get_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
|
EX(object).ptr = get_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
|
||||||
|
@ -1614,6 +1622,7 @@ binary_assign_op_addr: {
|
||||||
EX(object).ptr = this_ptr;
|
EX(object).ptr = this_ptr;
|
||||||
}
|
}
|
||||||
active_function_table = &Z_OBJCE_P(EX(object).ptr)->function_table;
|
active_function_table = &Z_OBJCE_P(EX(object).ptr)->function_table;
|
||||||
|
EX(calling_namespace) = Z_OBJCE_P(EX(object).ptr);
|
||||||
}
|
}
|
||||||
if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) {
|
if (zend_hash_find(active_function_table, function_name->value.str.val, function_name->value.str.len+1, (void **) &function)==FAILURE) {
|
||||||
zend_error(E_ERROR, "Call to undefined function: %s()", function_name->value.str.val);
|
zend_error(E_ERROR, "Call to undefined function: %s()", function_name->value.str.val);
|
||||||
|
@ -2058,9 +2067,6 @@ send_by_ref:
|
||||||
NEXT_OPCODE();
|
NEXT_OPCODE();
|
||||||
case ZEND_NEW:
|
case ZEND_NEW:
|
||||||
{
|
{
|
||||||
if (EX(Ts)[EX(opline)->op1.u.var].EA.class_entry->is_namespace) {
|
|
||||||
zend_error(E_ERROR, "Cannot instantiate a namespace");
|
|
||||||
}
|
|
||||||
EX(Ts)[EX(opline)->result.u.var].var.ptr_ptr = &EX(Ts)[EX(opline)->result.u.var].var.ptr;
|
EX(Ts)[EX(opline)->result.u.var].var.ptr_ptr = &EX(Ts)[EX(opline)->result.u.var].var.ptr;
|
||||||
ALLOC_ZVAL(EX(Ts)[EX(opline)->result.u.var].var.ptr);
|
ALLOC_ZVAL(EX(Ts)[EX(opline)->result.u.var].var.ptr);
|
||||||
object_init_ex(EX(Ts)[EX(opline)->result.u.var].var.ptr, EX(Ts)[EX(opline)->op1.u.var].EA.class_entry);
|
object_init_ex(EX(Ts)[EX(opline)->result.u.var].var.ptr, EX(Ts)[EX(opline)->op1.u.var].EA.class_entry);
|
||||||
|
|
|
@ -116,9 +116,6 @@ struct _zend_compiler_globals {
|
||||||
int interactive;
|
int interactive;
|
||||||
|
|
||||||
zend_bool increment_lineno;
|
zend_bool increment_lineno;
|
||||||
|
|
||||||
char *namespace;
|
|
||||||
int namespace_len;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -238,9 +238,8 @@ unticked_declaration_statement:
|
||||||
'(' parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
|
'(' parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
|
||||||
| T_OLD_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$4, 0, $3.op_type TSRMLS_CC); }
|
| T_OLD_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$4, 0, $3.op_type TSRMLS_CC); }
|
||||||
parameter_list '(' inner_statement_list ')' ';' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
|
parameter_list '(' inner_statement_list ')' ';' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
|
||||||
| T_NAMESPACE T_STRING { zend_do_begin_class_declaration(&$1, &$2, NULL, 1 TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
|
| T_CLASS T_STRING { zend_do_begin_class_declaration(&$1, &$2, NULL TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
|
||||||
| T_CLASS T_STRING { zend_do_begin_class_declaration(&$1, &$2, NULL, 0 TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
|
| T_CLASS T_STRING T_EXTENDS T_STRING { zend_do_begin_class_declaration(&$1, &$2, &$4 TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
|
||||||
| T_CLASS T_STRING T_EXTENDS T_STRING { zend_do_begin_class_declaration(&$1, &$2, &$4, 0 TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
@ -394,9 +393,8 @@ class_statement:
|
||||||
parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
|
parameter_list ')' '{' inner_statement_list '}' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
|
||||||
| T_OLD_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$4, 1, $3.op_type TSRMLS_CC); }
|
| T_OLD_FUNCTION { $1.u.opline_num = CG(zend_lineno); } is_reference T_STRING { zend_do_begin_function_declaration(&$1, &$4, 1, $3.op_type TSRMLS_CC); }
|
||||||
parameter_list '(' inner_statement_list ')' ';' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
|
parameter_list '(' inner_statement_list ')' ';' { zend_do_end_function_declaration(&$1 TSRMLS_CC); }
|
||||||
| T_NAMESPACE T_STRING { zend_do_begin_class_declaration(&$1, &$2, NULL, 1 TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
|
| T_CLASS T_STRING { zend_do_begin_class_declaration(&$1, &$2, NULL TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
|
||||||
| T_CLASS T_STRING { zend_do_begin_class_declaration(&$1, &$2, NULL, 0 TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
|
| T_CLASS T_STRING T_EXTENDS T_STRING { zend_do_begin_class_declaration(&$1, &$2, &$4 TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
|
||||||
| T_CLASS T_STRING T_EXTENDS T_STRING { zend_do_begin_class_declaration(&$1, &$2, &$4, 0 TSRMLS_CC); } '{' class_statement_list '}' { zend_do_end_class_declaration(&$1 TSRMLS_CC); }
|
|
||||||
;
|
;
|
||||||
|
|
||||||
is_reference:
|
is_reference:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue