mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Allow namespaces to have a number of parts. I.e., now you can do:
namespace foo { function abc() {} } ... namespace foo { functio def() {} }
This commit is contained in:
parent
9729930343
commit
e645f20d07
5 changed files with 54 additions and 74 deletions
|
@ -26,6 +26,7 @@
|
|||
#include "zend_API.h"
|
||||
#include "zend_fast_cache.h"
|
||||
|
||||
#define IN_NAMESPACE() (CG(active_namespace) != &CG(global_namespace))
|
||||
|
||||
ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);
|
||||
|
||||
|
@ -986,6 +987,10 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
|
|||
} else if ((function_name->u.constant.value.str.len == sizeof(ZEND_SET_FUNC_NAME)-1) && (!memcmp(function_name->u.constant.value.str.val, ZEND_SET_FUNC_NAME, sizeof(ZEND_SET_FUNC_NAME)))) {
|
||||
CG(active_class_entry)->__set = (zend_function *) CG(active_op_array);
|
||||
}
|
||||
} else if(IN_NAMESPACE()) {
|
||||
if (zend_hash_add(&CG(active_namespace)->function_table, name, name_len+1, &op_array, sizeof(zend_op_array), (void **) &CG(active_op_array)) == FAILURE) {
|
||||
zend_error(E_COMPILE_ERROR, "Cannot redeclare %s::%s()", CG(active_namespace)->name, name);
|
||||
}
|
||||
} else {
|
||||
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
|
||||
|
@ -3196,21 +3201,27 @@ void zend_init_namespace(zend_namespace *ns TSRMLS_DC)
|
|||
|
||||
void zend_do_begin_namespace(znode *ns_token, znode *ns_name TSRMLS_DC)
|
||||
{
|
||||
zend_namespace *ns = emalloc(sizeof(zend_namespace));
|
||||
zend_namespace *ns, **pns;
|
||||
zend_op *opline;
|
||||
|
||||
zend_str_tolower(ns_name->u.constant.value.str.val, ns_name->u.constant.value.str.len);
|
||||
ns->name = ns_name->u.constant.value.str.val;
|
||||
ns->name_length = ns_name->u.constant.value.str.len;
|
||||
|
||||
if(zend_hash_add(&CG(global_namespace).class_table, ns->name, ns->name_length+1, (void **)&ns, sizeof(zend_namespace *), NULL) != SUCCESS) {
|
||||
efree(ns);
|
||||
zend_error(E_COMPILE_ERROR, "Cannot redefine namespace '%s' - class or namespace with this name already defined", ns->name);
|
||||
if(zend_hash_find(&CG(global_namespace).class_table, ns_name->u.constant.value.str.val, ns_name->u.constant.value.str.len+1, (void **)&pns) == SUCCESS) {
|
||||
ns = *pns;
|
||||
if(ns->type != ZEND_NAMESPACE || ns == CG(active_namespace)) {
|
||||
zend_error(E_COMPILE_ERROR, "Cannot redefine namespace '%s' - class or namespace with this name already defined", ns->name);
|
||||
}
|
||||
} else {
|
||||
ns = emalloc(sizeof(zend_namespace));
|
||||
ns->name = ns_name->u.constant.value.str.val;
|
||||
ns->name_length = ns_name->u.constant.value.str.len;
|
||||
zend_hash_add(&CG(global_namespace).class_table, ns->name, ns->name_length+1, (void **)&ns, sizeof(zend_namespace *), NULL);
|
||||
zend_init_namespace(ns TSRMLS_CC);
|
||||
}
|
||||
|
||||
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
|
||||
opline->opcode = ZEND_DECLARE_NAMESPACE;
|
||||
opline->opcode = ZEND_START_NAMESPACE;
|
||||
opline->op1.op_type = IS_CONST;
|
||||
opline->op1.u.constant.type = IS_STRING;
|
||||
opline->op1.u.constant.value.str.val = estrndup(ns->name, ns->name_length);
|
||||
|
@ -3218,15 +3229,8 @@ void zend_do_begin_namespace(znode *ns_token, znode *ns_name TSRMLS_DC)
|
|||
opline->op1.u.constant.refcount = 1;
|
||||
SET_UNUSED(opline->op2);
|
||||
|
||||
zend_init_namespace(ns TSRMLS_CC);
|
||||
|
||||
ns->constructor = emalloc(sizeof(zend_op_array));
|
||||
init_op_array((zend_op_array *)ns->constructor, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
|
||||
ns->constructor->op_array.ns = CG(active_namespace);
|
||||
|
||||
ns_token->u.op_array = CG(active_op_array);
|
||||
|
||||
CG(active_op_array) = &ns->constructor->op_array;
|
||||
ns_token->u.previously_active_namespace = CG(active_namespace);
|
||||
CG(active_namespace) = ns;
|
||||
|
||||
/* new symbol tables */
|
||||
|
@ -3236,20 +3240,25 @@ void zend_do_begin_namespace(znode *ns_token, znode *ns_name TSRMLS_DC)
|
|||
|
||||
void zend_do_end_namespace(znode *ns_token TSRMLS_DC)
|
||||
{
|
||||
zend_namespace *ns = CG(active_op_array)->ns;
|
||||
int handle = CG(handle_op_arrays);
|
||||
zend_namespace *ns = ns_token->u.previously_active_namespace;
|
||||
zend_op *opline;
|
||||
|
||||
|
||||
zend_do_return(NULL, 0 TSRMLS_CC);
|
||||
CG(handle_op_arrays) = 0;
|
||||
pass_two(CG(active_op_array) TSRMLS_CC);
|
||||
CG(handle_op_arrays) = handle;
|
||||
|
||||
CG(active_op_array)->ns = CG(active_namespace);
|
||||
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
|
||||
opline->opcode = ZEND_START_NAMESPACE;
|
||||
if(ns != &CG(global_namespace)) {
|
||||
opline->op1.op_type = IS_CONST;
|
||||
opline->op1.u.constant.type = IS_STRING;
|
||||
opline->op1.u.constant.value.str.val = estrndup(ns->name, ns->name_length);
|
||||
opline->op1.u.constant.value.str.len = ns->name_length;
|
||||
opline->op1.u.constant.refcount = 1;
|
||||
} else {
|
||||
SET_UNUSED(opline->op1);
|
||||
}
|
||||
SET_UNUSED(opline->op2);
|
||||
|
||||
CG(active_namespace) = ns;
|
||||
CG(active_op_array) = ns_token->u.op_array;
|
||||
/* restore symbol tables */
|
||||
/* restore symbol tables */
|
||||
CG(class_table) = &CG(active_namespace)->class_table;
|
||||
CG(function_table) = &CG(active_namespace)->function_table;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ typedef struct _znode {
|
|||
zend_uint var; /* dummy */
|
||||
zend_uint type;
|
||||
} EA;
|
||||
zend_namespace *previously_active_namespace;
|
||||
} u;
|
||||
} znode;
|
||||
|
||||
|
@ -645,7 +646,7 @@ int zendlex(znode *zendlval TSRMLS_DC);
|
|||
|
||||
#define ZEND_RAISE_ABSTRACT_ERROR 142
|
||||
|
||||
#define ZEND_DECLARE_NAMESPACE 143
|
||||
#define ZEND_START_NAMESPACE 143
|
||||
|
||||
/* end of block */
|
||||
|
||||
|
|
|
@ -3927,55 +3927,27 @@ int zend_nop_handler(ZEND_OPCODE_HANDLER_ARGS)
|
|||
NEXT_OPCODE();
|
||||
}
|
||||
|
||||
int zend_declare_namespace_handler(ZEND_OPCODE_HANDLER_ARGS)
|
||||
int zend_start_namespace_handler(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op_array *new_op_array=NULL;
|
||||
zval **original_return_value = EG(return_value_ptr_ptr);
|
||||
zval *namespace_name = get_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
|
||||
zval *namespace_name;
|
||||
zend_namespace **pns;
|
||||
zval *saved_object;
|
||||
zend_function *saved_function;
|
||||
zend_namespace *active_namespace = EG(active_namespace);
|
||||
|
||||
if (Z_TYPE_P(namespace_name) != IS_STRING) {
|
||||
zend_error(E_ERROR, "Internal error: Invalid type in namespace definition - %d", Z_TYPE_P(namespace_name));
|
||||
if(EX(opline)->op1.op_type != IS_UNUSED) {
|
||||
namespace_name= get_zval_ptr(&EX(opline)->op1, EX(Ts), &EG(free_op1), BP_VAR_R);
|
||||
if (Z_TYPE_P(namespace_name) != IS_STRING) {
|
||||
zend_error(E_ERROR, "Internal error: Invalid type in namespace definition - %d", Z_TYPE_P(namespace_name));
|
||||
}
|
||||
|
||||
if(zend_hash_find(&EG(global_namespace_ptr)->class_table, Z_STRVAL_P(namespace_name), Z_STRLEN_P(namespace_name)+1, (void **)&pns) != SUCCESS || (*pns)->type != ZEND_NAMESPACE) {
|
||||
zend_error(E_ERROR, "Internal error: Cannot locate namespace '%s'", Z_STRVAL_P(namespace_name));
|
||||
}
|
||||
} else {
|
||||
pns = &EG(global_namespace_ptr);
|
||||
}
|
||||
|
||||
if(zend_hash_find(&EG(global_namespace_ptr)->class_table, Z_STRVAL_P(namespace_name), Z_STRLEN_P(namespace_name)+1, (void **)&pns) != SUCCESS || (*pns)->type != ZEND_NAMESPACE) {
|
||||
zend_error(E_ERROR, "Internal error: Cannot locate namespace '%s'", Z_STRVAL_P(namespace_name));
|
||||
if(EG(active_namespace) != *pns) {
|
||||
zend_switch_namespace(*pns TSRMLS_CC);
|
||||
}
|
||||
|
||||
new_op_array = (zend_op_array *)(*pns)->constructor;
|
||||
|
||||
FREE_OP(EX(Ts), &EX(opline)->op1, EG(free_op1));
|
||||
EX_T(EX(opline)->result.u.var).var.ptr_ptr = &EX_T(EX(opline)->result.u.var).var.ptr;
|
||||
|
||||
EG(return_value_ptr_ptr) = EX_T(EX(opline)->result.u.var).var.ptr_ptr;
|
||||
EG(active_op_array) = new_op_array;
|
||||
EX_T(EX(opline)->result.u.var).var.ptr = NULL;
|
||||
|
||||
saved_object = EX(object);
|
||||
saved_function = EX(function_state).function;
|
||||
|
||||
EX(function_state).function = (zend_function *) new_op_array;
|
||||
EX(object) = NULL;
|
||||
|
||||
zend_execute(new_op_array TSRMLS_CC);
|
||||
|
||||
if(EG(active_namespace) != active_namespace) {
|
||||
zend_switch_namespace(active_namespace TSRMLS_CC);
|
||||
}
|
||||
EX(function_state).function = saved_function;
|
||||
EX(object) = saved_object;
|
||||
|
||||
if (EX_T(EX(opline)->result.u.var).var.ptr) {
|
||||
zval_ptr_dtor(&EX_T(EX(opline)->result.u.var).var.ptr);
|
||||
}
|
||||
|
||||
EG(opline_ptr) = &EX(opline);
|
||||
EG(active_op_array) = op_array;
|
||||
EG(function_state_ptr) = &EX(function_state);
|
||||
EG(return_value_ptr_ptr) = original_return_value;
|
||||
NEXT_OPCODE();
|
||||
}
|
||||
|
||||
|
@ -4153,7 +4125,7 @@ void zend_init_opcodes_handlers()
|
|||
zend_opcode_handlers[ZEND_DECLARE_FUNCTION] = zend_declare_function_handler;
|
||||
|
||||
zend_opcode_handlers[ZEND_RAISE_ABSTRACT_ERROR] = zend_raise_abstract_error_handler;
|
||||
zend_opcode_handlers[ZEND_DECLARE_NAMESPACE] = zend_declare_namespace_handler;
|
||||
zend_opcode_handlers[ZEND_START_NAMESPACE] = zend_start_namespace_handler;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -302,7 +302,7 @@ namespace_statement_list:
|
|||
namespace_statement:
|
||||
T_VAR namespace_var_declaration_list ';'
|
||||
| namespace_const_declaration ';'
|
||||
| function_declaration_statement { zend_do_early_binding(TSRMLS_C); }
|
||||
| function_declaration_statement
|
||||
| class_declaration_statement
|
||||
| namespace_declaration_statement
|
||||
;
|
||||
|
|
|
@ -181,8 +181,6 @@ ZEND_API void destroy_zend_namespace(zend_namespace **pns)
|
|||
zend_hash_destroy(&ns->constants_table);
|
||||
zend_hash_destroy(ns->static_members);
|
||||
FREE_HASHTABLE(ns->static_members);
|
||||
destroy_op_array(ns->constructor);
|
||||
efree(ns->constructor);
|
||||
efree(ns->name);
|
||||
efree(ns);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue