diff options
-rw-r--r-- | Zend/zend_compile.c | 61 | ||||
-rw-r--r-- | Zend/zend_compile.h | 3 | ||||
-rw-r--r-- | Zend/zend_execute.c | 58 | ||||
-rw-r--r-- | Zend/zend_language_parser.y | 2 | ||||
-rw-r--r-- | Zend/zend_opcode.c | 2 |
5 files changed, 53 insertions, 73 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 2133d549f0..31306d82f2 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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; } diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 1ac590c5c4..4a970881f8 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -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 */ diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 004f427a34..44f9a43d00 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -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)); + 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); } - 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); + if(EG(active_namespace) != *pns) { + zend_switch_namespace(*pns 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; } /* diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 0fe7d17a54..0ed55aa1a7 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -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 ; diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 599b988024..334788a908 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -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); } |