Browse Source

MEGA-patch: namespaces are R.I.P.

migration/unlabaled-1.3.2
Stanislav Malyshev 23 years ago
parent
commit
f7f5a5ea6b
  1. 46
      Zend/zend.c
  2. 13
      Zend/zend.h
  3. 98
      Zend/zend_API.c
  4. 7
      Zend/zend_API.h
  5. 101
      Zend/zend_builtin_functions.c
  6. 182
      Zend/zend_compile.c
  7. 20
      Zend/zend_compile.h
  8. 3
      Zend/zend_constants.c
  9. 93
      Zend/zend_execute.c
  10. 1
      Zend/zend_execute.h
  11. 56
      Zend/zend_execute_API.c
  12. 6
      Zend/zend_globals.h
  13. 94
      Zend/zend_language_parser.y
  14. 46
      Zend/zend_language_scanner.l
  15. 36
      Zend/zend_object_handlers.c
  16. 34
      Zend/zend_opcode.c

46
Zend/zend.c

@ -30,14 +30,15 @@
#include "zend_ini.h"
#ifdef ZTS
# define GLOBAL_FUNCTION_TABLE &global_namespace.function_table
# define GLOBAL_CLASS_TABLE &global_namespace.class_table
# define GLOBAL_CONSTANTS_TABLE &global_namespace.constants_table
# define GLOBAL_AUTO_GLOBALS_TABLE global_auto_globals_table
# define GLOBAL_FUNCTION_TABLE global_function_table
# define GLOBAL_CLASS_TABLE global_class_table
# define GLOBAL_CONSTANTS_TABLE global_constants_table
# define GLOBAL_AUTO_GLOBALS_TABLE global_auto_globals_table
#else
# define GLOBAL_FUNCTION_TABLE CG(function_table)
# define GLOBAL_CLASS_TABLE CG(class_table)
# define GLOBAL_AUTO_GLOBALS_TABLE CG(auto_globals)
# define GLOBAL_FUNCTION_TABLE CG(function_table)
# define GLOBAL_CLASS_TABLE CG(class_table)
# define GLOBAL_CONSTANTS_TABLE CG(zend_constants)
# define GLOBAL_AUTO_GLOBALS_TABLE CG(auto_globals)
#endif
#if defined(ZEND_WIN32) && ZEND_DEBUG
@ -94,7 +95,9 @@ ZEND_API int compiler_globals_id;
ZEND_API int executor_globals_id;
ZEND_API int alloc_globals_id;
zend_class_entry global_main_class;
zend_namespace global_namespace;
HashTable *global_function_table;
HashTable *global_class_table;
HashTable *global_constants_table;
HashTable *global_auto_globals_table;
#endif
@ -412,13 +415,13 @@ static void compiler_globals_ctor(zend_compiler_globals *compiler_globals TSRMLS
compiler_globals->compiled_filename = NULL;
compiler_globals->function_table = &compiler_globals->global_namespace.function_table;
zend_hash_init_ex(compiler_globals->function_table, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0);
zend_hash_copy(compiler_globals->function_table, GLOBAL_FUNCTION_TABLE, NULL, &tmp_func, sizeof(zend_function));
compiler_globals->function_table = (HashTable *) malloc(sizeof(HashTable));
zend_hash_init_ex(compiler_globals->function_table, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0);
zend_hash_copy(compiler_globals->function_table, global_function_table, NULL, &tmp_func, sizeof(zend_function));
compiler_globals->class_table = &compiler_globals->global_namespace.class_table;
zend_hash_init_ex(compiler_globals->class_table, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
zend_hash_copy(compiler_globals->class_table, GLOBAL_CLASS_TABLE, (copy_ctor_func_t) zend_class_add_ref, &tmp_class, sizeof(zend_class_entry *));
compiler_globals->class_table = (HashTable *) malloc(sizeof(HashTable));
zend_hash_init_ex(compiler_globals->class_table, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
zend_hash_copy(compiler_globals->class_table, global_class_table, (copy_ctor_func_t) zend_class_add_ref, &tmp_class, sizeof(zend_class_entry));
zend_set_default_compile_time_values(TSRMLS_C);
@ -455,7 +458,6 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals TSRMLS
EG(user_exception_handler) = NULL;
EG(in_execution) = 0;
EG(current_execute_data) = NULL;
EG(active_namespace) = NULL;
}
@ -563,12 +565,9 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions, i
zend_version_info = strdup(ZEND_CORE_VERSION_INFO);
zend_version_info_length = sizeof(ZEND_CORE_VERSION_INFO)-1;
#ifndef ZTS
GLOBAL_FUNCTION_TABLE = &compiler_globals.global_namespace.function_table;
GLOBAL_CLASS_TABLE = &compiler_globals.global_namespace.class_table;
compiler_globals.global_namespace.static_members = NULL;
#endif
GLOBAL_AUTO_GLOBALS_TABLE = (HashTable *) malloc(sizeof(HashTable));
GLOBAL_FUNCTION_TABLE = (HashTable *) malloc(sizeof(HashTable));
GLOBAL_CLASS_TABLE = (HashTable *) malloc(sizeof(HashTable));
GLOBAL_AUTO_GLOBALS_TABLE = (HashTable *) malloc(sizeof(HashTable));
zend_hash_init_ex(GLOBAL_FUNCTION_TABLE, 100, NULL, ZEND_FUNCTION_DTOR, 1, 0);
zend_hash_init_ex(GLOBAL_CLASS_TABLE, 10, NULL, ZEND_CLASS_DTOR, 1, 0);
@ -775,11 +774,6 @@ void zend_deactivate(TSRMLS_D)
EG(opline_ptr) = NULL;
EG(active_symbol_table) = NULL;
/* restore namespace to global */
zend_switch_namespace(EG(global_namespace_ptr) TSRMLS_CC);
CG(function_table) = EG(function_table);
CG(class_table) = EG(class_table);
zend_try {
shutdown_scanner(TSRMLS_C);
} zend_end_try();

13
Zend/zend.h

@ -264,17 +264,6 @@ struct _zval_struct {
struct _zend_op_array;
/* typedef struct _zend_namespace {
char *name;
zend_uint name_length;
HashTable function_table;
HashTable class_table;
HashTable constants_table;
HashTable *global_variables;
struct _zend_op_array *op_array;
} zend_namespace;
*/
typedef struct _zend_function_entry {
char *fname;
void (*handler)(INTERNAL_FUNCTION_PARAMETERS);
@ -349,8 +338,6 @@ struct _zend_class_entry {
#endif
};
typedef struct _zend_class_entry zend_namespace; /* namespace is the same as class */
#include "zend_stream.h"
typedef struct _zend_utility_functions {
void (*error_function)(int type, const char *error_filename, const uint error_lineno, const char *format, va_list args);

98
Zend/zend_API.c

@ -1146,8 +1146,7 @@ int zend_register_functions(zend_class_entry *scope, zend_function_entry *functi
int error_type;
zend_function *ctor = NULL, *dtor = NULL, *clone = NULL;
char *lowercase_name;
int fname_len, is_namespace = 0;
zend_namespace *scope_namespace;
int fname_len;
if (type==MODULE_PERSISTENT) {
error_type = E_CORE_WARNING;
@ -1160,20 +1159,12 @@ int zend_register_functions(zend_class_entry *scope, zend_function_entry *functi
}
internal_function->type = ZEND_INTERNAL_FUNCTION;
if(scope) {
scope_namespace = scope->ns;
is_namespace = (scope->type == ZEND_INTERNAL_NAMESPACE || scope->type == ZEND_USER_NAMESPACE) ? 1 : 0;
} else {
scope_namespace = EG(active_namespace);
}
while (ptr->fname) {
internal_function->handler = ptr->handler;
internal_function->arg_types = ptr->func_arg_types;
internal_function->function_name = ptr->fname;
internal_function->scope = scope;
internal_function->fn_flags = ZEND_ACC_PUBLIC;
internal_function->ns = scope_namespace;
internal_function->prototype = NULL;
if (!internal_function->handler) {
zend_error(error_type, "Null function defined as active function");
@ -1189,23 +1180,18 @@ int zend_register_functions(zend_class_entry *scope, zend_function_entry *functi
break;
}
if (scope) {
if (is_namespace) {
/* if namespace all methods must be "static final" */
reg_function->common.fn_flags = ZEND_ACC_FINAL | ZEND_ACC_STATIC;
} else {
/* if class not namespace then look for ctor, dtor, clone
* If it's an old-style constructor, store it only if we don't have
* a constructor already.
*/
if (!strcmp(ptr->fname, scope->name) && !ctor) {
ctor = reg_function;
} else if (!strcmp(ptr->fname, ZEND_CONSTRUCTOR_FUNC_NAME)) {
ctor = reg_function;
} else if (!strcmp(ptr->fname, ZEND_DESTRUCTOR_FUNC_NAME)) {
dtor = reg_function;
} else if (!strcmp(ptr->fname, ZEND_CLONE_FUNC_NAME)) {
clone = reg_function;
}
/* Look for ctor, dtor, clone
* If it's an old-style constructor, store it only if we don't have
* a constructor already.
*/
if (!strcmp(ptr->fname, scope->name) && !ctor) {
ctor = reg_function;
} else if (!strcmp(ptr->fname, ZEND_CONSTRUCTOR_FUNC_NAME)) {
ctor = reg_function;
} else if (!strcmp(ptr->fname, ZEND_DESTRUCTOR_FUNC_NAME)) {
dtor = reg_function;
} else if (!strcmp(ptr->fname, ZEND_CLONE_FUNC_NAME)) {
clone = reg_function;
}
}
ptr++;
@ -1392,64 +1378,6 @@ ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *orig_c
return class_entry;
}
ZEND_API zend_class_entry *zend_register_internal_ns_class(zend_class_entry *class_entry, zend_class_entry *parent_ce, zend_namespace *ns, char *ns_name TSRMLS_DC)
{
zend_class_entry *register_class;
zend_namespace *orig_namespace = NULL;
HashTable *orig_class_table = NULL;
int restore_orig = 0;
if (!ns && ns_name) {
zend_namespace **pns;
size_t ns_name_length = strlen(ns_name);
char *lowercase_name = malloc(ns_name_length + 1);
zend_str_tolower_copy(lowercase_name, ns_name, ns_name_length);
if (zend_hash_find(&CG(global_namespace).class_table, lowercase_name, ns_name_length+1, (void **)&pns) == FAILURE) {
free(lowercase_name);
return NULL;
} else {
ns = *pns;
}
free(lowercase_name);
}
if (EG(active_namespace) != ns) {
restore_orig = 1;
orig_namespace = CG(active_namespace);
CG(active_namespace) = ns;
orig_class_table = CG(class_table);
CG(class_table) = &ns->class_table;
}
class_entry->ns = ns;
register_class = zend_register_internal_class_ex(class_entry, parent_ce, NULL TSRMLS_CC);
if (restore_orig) {
CG(active_namespace) = orig_namespace;
CG(class_table) = orig_class_table;
}
return register_class;
}
ZEND_API zend_namespace *zend_register_internal_namespace(zend_namespace *orig_ns TSRMLS_DC)
{
zend_namespace *ns = malloc(sizeof(zend_namespace));
char *lowercase_name = malloc(orig_ns->name_length + 1);
*ns = *orig_ns;
ns->type = ZEND_INTERNAL_NAMESPACE;
zend_init_namespace(ns TSRMLS_CC);
zend_str_tolower_copy(lowercase_name, orig_ns->name, orig_ns->name_length);
zend_hash_update(&CG(global_namespace).class_table, lowercase_name, ns->name_length+1, &ns, sizeof(zend_namespace *), NULL);
free(lowercase_name);
if (ns->builtin_functions) {
zend_register_functions(ns, ns->builtin_functions, &ns->function_table, MODULE_PERSISTENT TSRMLS_CC);
}
return ns;
}
ZEND_API int zend_set_hash_symbol(zval *symbol, char *name, int name_length,
zend_bool is_ref, int num_symbol_tables, ...)
{

7
Zend/zend_API.h

@ -106,11 +106,6 @@ BEGIN_EXTERN_C()
class_container.num_interfaces = 0; \
}
#define INIT_NAMESPACE(ns_container, ns_name) INIT_CLASS_ENTRY(ns_container, ns_name, NULL)
#define INIT_NAMESPACE_WITH_FUNCS(ns_container, ns_name, functions) INIT_CLASS_ENTRY(ns_container, ns_name, functions)
int zend_next_free_module(void);
ZEND_API int zend_get_parameters(int ht, int param_count, ...);
@ -142,8 +137,6 @@ ZEND_API int zend_register_module(zend_module_entry *module_entry);
ZEND_API zend_class_entry *zend_register_internal_class(zend_class_entry *class_entry TSRMLS_DC);
ZEND_API zend_class_entry *zend_register_internal_class_ex(zend_class_entry *class_entry, zend_class_entry *parent_ce, char *parent_name TSRMLS_DC);
ZEND_API zend_class_entry *zend_register_internal_ns_class(zend_class_entry *class_entry, zend_class_entry *parent_ce, zend_namespace *ns, char *ns_name TSRMLS_DC);
ZEND_API zend_namespace *zend_register_internal_namespace(zend_namespace *ns TSRMLS_DC);
ZEND_API int zend_disable_function(char *function_name, uint function_name_length TSRMLS_DC);
ZEND_API int zend_disable_class(char *class_name, uint class_name_length TSRMLS_DC);

101
Zend/zend_builtin_functions.c

@ -577,7 +577,7 @@ ZEND_FUNCTION(get_parent_class)
SEPARATE_ZVAL(arg);
zend_str_tolower(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg));
if (zend_lookup_ns_class(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &pce TSRMLS_CC) == SUCCESS) {
if (zend_lookup_class(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), &pce TSRMLS_CC) == SUCCESS) {
ce = *pce;
}
}
@ -617,7 +617,7 @@ static void is_a_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool only_subclass)
lcname = zend_str_tolower_dup(Z_STRVAL_PP(class_name), Z_STRLEN_PP(class_name));
if (zend_lookup_ns_class(lcname, Z_STRLEN_PP(class_name), &ce TSRMLS_CC) == FAILURE) {
if (zend_lookup_class(lcname, Z_STRLEN_PP(class_name), &ce TSRMLS_CC) == FAILURE) {
efree(lcname);
retval = 0;
} else {
@ -674,7 +674,7 @@ ZEND_FUNCTION(get_class_vars)
convert_to_string_ex(class_name);
lcname = zend_str_tolower_dup((*class_name)->value.str.val, (*class_name)->value.str.len);
if (zend_lookup_ns_class(lcname, Z_STRLEN_PP(class_name), &pce TSRMLS_CC) == FAILURE) {
if (zend_lookup_class(lcname, Z_STRLEN_PP(class_name), &pce TSRMLS_CC) == FAILURE) {
efree(lcname);
RETURN_FALSE;
} else {
@ -741,7 +741,7 @@ ZEND_FUNCTION(get_class_methods)
SEPARATE_ZVAL(class);
zend_str_tolower(Z_STRVAL_PP(class), Z_STRLEN_PP(class));
if (zend_lookup_ns_class(Z_STRVAL_PP(class), Z_STRLEN_PP(class), &pce TSRMLS_CC) == SUCCESS) {
if (zend_lookup_class(Z_STRVAL_PP(class), Z_STRLEN_PP(class), &pce TSRMLS_CC) == SUCCESS) {
ce = *pce;
}
}
@ -795,27 +795,6 @@ ZEND_FUNCTION(method_exists)
}
/* }}} */
static inline zend_namespace *get_namespace_from_zval(zval **namespace_name TSRMLS_DC)
{
zend_namespace **pns;
char *str_ns_name;
convert_to_string_ex(namespace_name);
if(!Z_STRVAL_PP(namespace_name) || !Z_STRLEN_PP(namespace_name)) {
return EG(global_namespace_ptr);
}
str_ns_name = zend_str_tolower_dup(Z_STRVAL_PP(namespace_name), Z_STRLEN_PP(namespace_name));
if(zend_hash_find(&EG(global_namespace_ptr)->class_table, str_ns_name, Z_STRLEN_PP(namespace_name)+1, (void **)&pns) == FAILURE || !CLASS_IS_NAMESPACE((*pns))) {
zend_error(E_WARNING, "Namespace '%s' is not defined!", Z_STRVAL_PP(namespace_name));
efree(str_ns_name);
return NULL;
}
efree(str_ns_name);
return *pns;
}
/* {{{ proto bool class_exists(string classname)
Checks if the class exists */
ZEND_FUNCTION(class_exists)
@ -830,7 +809,7 @@ ZEND_FUNCTION(class_exists)
convert_to_string_ex(class_name);
lcname = zend_str_tolower_dup((*class_name)->value.str.val, (*class_name)->value.str.len);
if (zend_lookup_ns_class(lcname, Z_STRLEN_PP(class_name), &ce TSRMLS_CC) == SUCCESS) {
if (zend_lookup_class(lcname, Z_STRLEN_PP(class_name), &ce TSRMLS_CC) == SUCCESS) {
efree(lcname);
RETURN_TRUE;
} else {
@ -847,7 +826,7 @@ ZEND_FUNCTION(function_exists)
{
zval **function_name;
zend_function *func;
char *lcname, *func_name, *func_name_end;
char *lcname, *func_name_end;
zend_bool retval;
if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &function_name)==FAILURE) {
@ -857,37 +836,8 @@ ZEND_FUNCTION(function_exists)
lcname = zend_str_tolower_dup((*function_name)->value.str.val, (*function_name)->value.str.len);
func_name_end = lcname + (*function_name)->value.str.len;
if((func_name = zend_memnstr(lcname, "::", sizeof("::")-1, func_name_end)) == NULL) {
retval = (zend_hash_find(EG(function_table), lcname, (*function_name)->value.str.len+1, (void **)&func) == SUCCESS);
} else {
/* handle ::f case */
if (func_name == lcname) {
retval = (zend_hash_find(EG(function_table), lcname+sizeof("::")-1, (*function_name)->value.str.len-(sizeof("::")-1)+1, (void **)&func) == SUCCESS);
} else {
/* handle ns::f case */
int ns_name_length = func_name - lcname;
char *ns_name;
zend_namespace **ns;
func_name += sizeof("::")-1;
if(func_name >= func_name_end) {
/* ns:: case */
retval = 0;
} else {
ns_name = estrndup(lcname, ns_name_length);
if (zend_hash_find(&EG(global_namespace_ptr)->class_table, ns_name, ns_name_length+1, (void **)&ns) == SUCCESS &&
CLASS_IS_NAMESPACE(*ns) &&
zend_hash_find(&(*ns)->function_table, func_name, func_name_end - func_name + 1, (void **)&func) == SUCCESS) {
retval = 1;
} else {
retval = 0;
}
efree(ns_name);
}
}
}
retval = (zend_hash_find(EG(function_table), lcname, (*function_name)->value.str.len+1, (void **)&func) == SUCCESS);
efree(lcname);
/*
@ -1119,44 +1069,21 @@ static int copy_class_name(zend_class_entry **pce, int num_args, va_list args, z
zend_class_entry *ce = *pce;
if (hash_key->nKeyLength==0 || hash_key->arKey[0]!=0) {
if (ce->type == ZEND_USER_NAMESPACE || ce->type == ZEND_INTERNAL_NAMESPACE) {
zval *subarray;
MAKE_STD_ZVAL(subarray);
array_init(subarray);
zend_hash_apply_with_arguments(&ce->class_table, (apply_func_args_t) copy_class_name, 1, subarray);
add_assoc_zval(array, ce->name, subarray);
} else {
add_next_index_stringl(array, ce->name, ce->name_length, 1);
}
add_next_index_stringl(array, ce->name, ce->name_length, 1);
}
return 0;
}
/* {{{ proto array get_declared_classes([string namespace])
/* {{{ proto array get_declared_classes()
Returns an array of all declared classes. */
ZEND_FUNCTION(get_declared_classes)
{
zval **namespace_name;
zend_namespace *ns;
if (ZEND_NUM_ARGS() != 0) {
if(ZEND_NUM_ARGS() > 1 || zend_get_parameters_ex(1, &namespace_name)==FAILURE) {
ZEND_WRONG_PARAM_COUNT();
}
ns = get_namespace_from_zval(namespace_name TSRMLS_CC);
if(!ns) {
RETURN_FALSE;
}
} else {
ns = EG(global_namespace_ptr);
}
if (ZEND_NUM_ARGS() != 0) {
ZEND_WRONG_PARAM_COUNT();
}
array_init(return_value);
zend_hash_apply_with_arguments(&ns->class_table, (apply_func_args_t) copy_class_name, 1, return_value);
zend_hash_apply_with_arguments(EG(class_table), (apply_func_args_t) copy_class_name, 1, return_value);
}
/* }}} */

182
Zend/zend_compile.c

@ -27,8 +27,6 @@
#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);
@ -83,7 +81,6 @@ void zend_init_compiler_data_structures(TSRMLS_D)
zend_stack_init(&CG(object_stack));
zend_stack_init(&CG(declare_stack));
CG(active_class_entry) = NULL;
CG(active_namespace) = &CG(global_namespace);
zend_llist_init(&CG(list_llist), sizeof(list_llist_element), NULL, 0);
zend_llist_init(&CG(dimension_llist), sizeof(int), NULL, 0);
zend_stack_init(&CG(list_stack));
@ -1008,7 +1005,6 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
op_array.fn_flags = fn_flags;
op_array.scope = CG(active_class_entry);
op_array.ns = CG(active_namespace);
op_array.prototype = NULL;
op_array.line_start = zend_get_compiled_lineno(TSRMLS_C);
@ -1060,10 +1056,6 @@ 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);
@ -1253,7 +1245,7 @@ void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC)
}
void zend_do_fetch_class(znode *result, znode *namespace_name, znode *class_name, zend_bool global_namespace TSRMLS_DC)
void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC)
{
long fetch_class_op_number;
zend_op *opline;
@ -1262,15 +1254,8 @@ void zend_do_fetch_class(znode *result, znode *namespace_name, znode *class_name
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = ZEND_FETCH_CLASS;
if (namespace_name) {
zend_str_tolower(namespace_name->u.constant.value.str.val, namespace_name->u.constant.value.str.len);
opline->op1 = *namespace_name;
} else {
SET_UNUSED(opline->op1);
if (global_namespace) {
opline->extended_value = ZEND_FETCH_CLASS_GLOBAL;
}
}
SET_UNUSED(opline->op1);
opline->extended_value = ZEND_FETCH_CLASS_GLOBAL;
CG(catch_begin) = fetch_class_op_number;
if (class_name->op_type == IS_CONST) {
zend_str_tolower(class_name->u.constant.value.str.val, class_name->u.constant.value.str.len);
@ -3422,166 +3407,6 @@ void zend_destroy_property_info(zend_property_info *property_info)
efree(property_info->name);
}
void zend_init_namespace(zend_namespace *ns TSRMLS_DC)
{
zend_bool persistent_hashes = (ns->type == ZEND_INTERNAL_NAMESPACE) ? 1 : 0;
ns->refcount = 1;
ns->constants_updated = 0;
ns->ce_flags = 0;
ns->filename = NULL;
ns->doc_comment = NULL;
ns->doc_comment_len = 0;
if (persistent_hashes) {
ns->static_members = (HashTable *) malloc(sizeof(HashTable));
} else {
ALLOC_HASHTABLE(ns->static_members);
}
zend_hash_init_ex(ns->static_members, 0, NULL, ZVAL_PTR_DTOR, persistent_hashes, 0);
zend_hash_init_ex(&ns->function_table, 10, NULL, ZEND_FUNCTION_DTOR, persistent_hashes, 0);
zend_hash_init_ex(&ns->class_table, 10, NULL, ZEND_CLASS_DTOR, persistent_hashes, 0);
zend_hash_init_ex(&ns->constants_table, 10, NULL, ZVAL_PTR_DTOR, persistent_hashes, 0);
ns->parent = NULL;
ns->num_interfaces = 0;
ns->interfaces = NULL;
ns->ns = NULL;
ns->constructor = NULL;
ns->destructor = NULL;
ns->clone = NULL;
ns->__get = NULL;
ns->__set = NULL;
ns->__call = NULL;
ns->create_object = NULL;
}
void zend_do_begin_namespace(znode *ns_token, znode *ns_name TSRMLS_DC)
{
zend_namespace *ns, **pns;
zend_op *opline;
zend_str_tolower(ns_name->u.constant.value.str.val, ns_name->u.constant.value.str.len);
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_USER_NAMESPACE || ns == CG(active_namespace)) {
zend_error(E_COMPILE_ERROR, "Cannot redefine namespace '%s' - class or namespace with this name already defined", ns->name);
}
FREE_PNODE(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;
ns->type = ZEND_USER_NAMESPACE;
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);
ns->line_start = zend_get_compiled_lineno(TSRMLS_C);
}
opline = get_next_op(CG(active_op_array) TSRMLS_CC);
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);
opline->op1.u.constant.value.str.len = ns->name_length;
opline->op1.u.constant.refcount = 1;
SET_UNUSED(opline->op2);
ns_token->u.previously_active_namespace = CG(active_namespace);
CG(active_namespace) = ns;
if (CG(doc_comment)) {
/*
* Do not overwrite previously declared doc comment in case the namespace is
* split over several parts.
*/
if (CG(active_namespace)->doc_comment == NULL) {
CG(active_namespace)->doc_comment = estrndup(CG(doc_comment), CG(doc_comment_len));
CG(active_namespace)->doc_comment_len = CG(doc_comment_len);
}
RESET_DOC_COMMENT();
}
/* new symbol tables */
CG(class_table) = &ns->class_table;
CG(function_table) = &ns->function_table;
}
void zend_do_end_namespace(znode *ns_token TSRMLS_DC)
{
zend_namespace *ns = ns_token->u.previously_active_namespace;
zend_op *opline;
/*
* If the filename field has not been initialized yet, it means that we are
* on the first definition of namespace and should capture the definition
* information.
*/
if (CG(active_namespace)->filename == NULL) {
CG(active_namespace)->filename = zend_get_compiled_filename(TSRMLS_C);
CG(active_namespace)->line_end = zend_get_compiled_lineno(TSRMLS_C);
}
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;
/* restore symbol tables */
CG(class_table) = &CG(active_namespace)->class_table;
CG(function_table) = &CG(active_namespace)->function_table;
}
void zend_do_declare_namespace_var(znode *var_name, znode *value TSRMLS_DC)
{
zval *var;
ALLOC_ZVAL(var);
if (value) {
*var = value->u.constant;
} else {
INIT_PZVAL(var);
var->type = IS_NULL;
}
zend_hash_update(CG(active_namespace)->static_members, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, &var, sizeof(zval *), NULL);
FREE_PNODE(var_name);
}
void zend_do_declare_namespace_constant(znode *var_name, znode *value TSRMLS_DC)
{
zval *var;
ALLOC_ZVAL(var);
if (value) {
*var = value->u.constant;
} else {
INIT_PZVAL(var);
var->type = IS_NULL;
}
zend_hash_update(&CG(active_namespace)->constants_table, var_name->u.constant.value.str.val, var_name->u.constant.value.str.len+1, &var, sizeof(zval *), NULL);
FREE_PNODE(var_name);
}
void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers TSRMLS_DC)
{
zend_bool persistent_hashes = (ce->type == ZEND_INTERNAL_CLASS) ? 1 : 0;
@ -3619,7 +3444,6 @@ void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers
ce->parent = NULL;
ce->num_interfaces = 0;
ce->interfaces = NULL;
ce->ns = CG(active_namespace);
}
/*

20
Zend/zend_compile.h

@ -64,7 +64,6 @@ typedef struct _znode {
zend_uint var; /* dummy */
zend_uint type;
} EA;
zend_namespace *previously_active_namespace;
} u;
} znode;
@ -128,7 +127,6 @@ struct _zend_op_array {
char *function_name;
zend_class_entry *scope;
zend_uint fn_flags;
zend_namespace *ns;
union _zend_function *prototype;
/* END of common elements */
@ -170,7 +168,6 @@ typedef struct _zend_internal_function {
char *function_name;
zend_class_entry *scope;
zend_uint fn_flags;
zend_namespace *ns;
union _zend_function *prototype;
/* END of common elements */
@ -188,7 +185,6 @@ typedef union _zend_function {
char *function_name;
zend_class_entry *scope;
zend_uint fn_flags;
zend_namespace *ns;
union _zend_function *prototype;
} common;
@ -333,7 +329,7 @@ void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initia
int zend_do_begin_function_call(znode *function_name TSRMLS_DC);
void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC);
void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC);
void zend_do_fetch_class(znode *result, znode *namespace_name, znode *class_name, zend_bool global_namespace TSRMLS_DC);
void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC);
void zend_do_fetch_class_name(znode *result, znode *class_entry, znode *class_name, zend_bool case_sensitive TSRMLS_DC);
void zend_do_begin_class_member_function_call(TSRMLS_D);
void zend_do_end_function_call(znode *function_name, znode *result, znode *argument_list, int is_method, int is_dynamic_fcall TSRMLS_DC);
@ -459,19 +455,11 @@ ZEND_API void destroy_zend_function(zend_function *function TSRMLS_DC);
ZEND_API void destroy_zend_class(zend_class_entry **pce);
void zend_class_add_ref(zend_class_entry **ce);
void zend_do_begin_namespace(znode *ns_token, znode *ns_name TSRMLS_DC);
void zend_do_end_namespace(znode *ns_token TSRMLS_DC);
void zend_init_namespace(zend_namespace *ns TSRMLS_DC);
void zend_do_declare_namespace_var(znode *name, znode *value TSRMLS_DC);
void zend_do_declare_namespace_constant(znode *name, znode *value TSRMLS_DC);
ZEND_API void destroy_zend_namespace(zend_namespace **pns);
void zend_duplicate_property_info(zend_property_info *property_info);
void zend_destroy_property_info(zend_property_info *property_info);
#define ZEND_FUNCTION_DTOR (void (*)(void *)) destroy_zend_function
#define ZEND_CLASS_DTOR (void (*)(void *)) destroy_zend_class
#define ZEND_NAMESPACE_DTOR (void (*)(void *)) destroy_zend_namespace
zend_op *get_next_op(zend_op_array *op_array TSRMLS_DC);
void init_op(zend_op *op TSRMLS_DC);
@ -679,7 +667,7 @@ int zendlex(znode *zendlval TSRMLS_DC);
#define ZEND_RAISE_ABSTRACT_ERROR 142
#define ZEND_START_NAMESPACE 143
#define ZEND_ADD_INTERFACE 144
#define ZEND_VERIFY_INSTANCEOF 145
@ -733,8 +721,6 @@ int zendlex(znode *zendlval TSRMLS_DC);
#define ZEND_INTERNAL_CLASS 1
#define ZEND_USER_CLASS 2
#define ZEND_INTERNAL_NAMESPACE 3
#define ZEND_USER_NAMESPACE 4
#define ZEND_EVAL (1<<0)
#define ZEND_INCLUDE (1<<1)
@ -764,8 +750,6 @@ int zendlex(znode *zendlval TSRMLS_DC);
#define ZEND_ARG_SEND_BY_REF (1<<0)
#define ZEND_ARG_COMPILE_TIME_BOUND (1<<1)
#define CLASS_IS_NAMESPACE(c) ((c)->type == ZEND_INTERNAL_NAMESPACE || (c)->type == ZEND_USER_NAMESPACE)
#define AI_USE_PTR(ai) \
if ((ai).ptr_ptr) { \
(ai).ptr = *((ai).ptr_ptr); \

3
Zend/zend_constants.c

@ -80,7 +80,7 @@ void clean_module_constants(int module_number TSRMLS_DC)
int zend_startup_constants(TSRMLS_D)
{
EG(zend_constants) = &CG(global_namespace).constants_table;
EG(zend_constants) = (HashTable *) malloc(sizeof(HashTable));
if (zend_hash_init(EG(zend_constants), 20, NULL, ZEND_CONSTANT_DTOR, 1)==FAILURE) {
return FAILURE;
@ -143,6 +143,7 @@ void zend_register_standard_constants(TSRMLS_D)
int zend_shutdown_constants(TSRMLS_D)
{
zend_hash_destroy(EG(zend_constants));
free(EG(zend_constants));
return SUCCESS;
}

93
Zend/zend_execute.c

@ -1232,9 +1232,6 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC)
*/
EX(function_state).function_symbol_table = NULL;
#endif
if(EG(active_namespace) != op_array->ns) {
zend_switch_namespace(op_array->ns TSRMLS_CC);
}
while (1) {
#ifdef ZEND_WIN32
@ -2342,9 +2339,6 @@ int zend_fetch_class_handler(ZEND_OPCODE_HANDLER_ARGS)
}
EX_T(EX(opline)->result.u.var).EA.class_entry = EG(scope);
NEXT_OPCODE();
} else if (EX(opline)->extended_value == ZEND_FETCH_CLASS_MAIN) {
EX_T(EX(opline)->result.u.var).EA.class_entry = EG(global_namespace_ptr);
NEXT_OPCODE();
} else if (EX(opline)->extended_value == ZEND_FETCH_CLASS_PARENT) {
if (!EG(scope)) {
zend_error(E_ERROR, "Cannot access parent:: when no class scope is active");
@ -2376,28 +2370,8 @@ int zend_fetch_class_handler(ZEND_OPCODE_HANDLER_ARGS)
if (!ce) {
int retval;
if (EX(opline)->op1.op_type == IS_UNUSED && EX(opline)->extended_value != ZEND_FETCH_CLASS_GLOBAL) {
if (EX(opline)->op1.op_type == IS_UNUSED) {
retval = zend_lookup_class(class_name_strval, class_name_strlen, &pce TSRMLS_CC);
if(retval == FAILURE) {
/* try namespace */
if(zend_hash_find(&EG(global_namespace_ptr)->class_table, class_name_strval, class_name_strlen+1, (void **)&pce) == SUCCESS && CLASS_IS_NAMESPACE((*pce))) {
retval = SUCCESS;
}
}
} else {
zend_namespace *ns;
/* Looking for namespace */
if(EX(opline)->extended_value == ZEND_FETCH_CLASS_GLOBAL) {
ns = EG(global_namespace_ptr);
} else {
if (zend_hash_find(&EG(global_namespace_ptr)->class_table, EX(opline)->op1.u.constant.value.str.val, EX(opline)->op1.u.constant.value.str.len+1, (void **)&pce) == FAILURE || !CLASS_IS_NAMESPACE((*pce))) {
zend_error(E_ERROR, "Namespace '%s' not found", EX(opline)->op1.u.constant.value.str.val);
}
ns = *pce;
}
retval = zend_hash_find(&ns->class_table, class_name_strval, class_name_strlen+1, (void **)&pce);
}
if (retval==SUCCESS) {
ce = *pce;
@ -2526,7 +2500,7 @@ int zend_init_static_method_call_handler(ZEND_OPCODE_HANDLER_ARGS)
}
if (EX(opline)->op1.op_type == IS_UNUSED) {
ce = EG(global_namespace_ptr);
ce = EG(class_table);
} else {
ce = EX_T(EX(opline)->op1.u.var).EA.class_entry;
}
@ -2573,10 +2547,7 @@ int zend_init_fcall_by_name_handler(ZEND_OPCODE_HANDLER_ARGS)
}
if (zend_hash_find(EG(function_table), function_name_strval, function_name_strlen+1, (void **) &function)==FAILURE) {
/* try global space also */
if(zend_hash_find(&EG(global_namespace_ptr)->function_table, function_name_strval, function_name_strlen+1, (void **) &function)==FAILURE) {
zend_error(E_ERROR, "Call to undefined function: %s()", function_name_strval);
}
zend_error(E_ERROR, "Call to undefined function: %s()", function_name_strval);
}
if (!is_const) {
@ -2598,7 +2569,6 @@ int zend_do_fcall_common_helper(ZEND_OPCODE_HANDLER_ARGS)
zend_class_entry *current_scope;
zval *current_this;
int return_value_used = RETURN_VALUE_USED(EX(opline));
zend_namespace *active_namespace = EG(active_namespace);
zend_ptr_stack_n_push(&EG(argument_stack), 2, (void *) EX(opline)->extended_value, NULL);
@ -2689,9 +2659,6 @@ int zend_do_fcall_common_helper(ZEND_OPCODE_HANDLER_ARGS)
EG(scope) = current_scope;
zend_ptr_stack_n_pop(&EG(arg_types_stack), 3, &EX(calling_scope), &EX(object), &EX(fbc));
if(EG(active_namespace) != active_namespace) {
zend_switch_namespace(active_namespace TSRMLS_CC);
}
EX(function_state).function = (zend_function *) op_array;
EG(function_state_ptr) = &EX(function_state);
zend_ptr_stack_clear_multiple(TSRMLS_C);
@ -3179,16 +3146,7 @@ int zend_fetch_constant_handler(ZEND_OPCODE_HANDLER_ARGS)
NEXT_OPCODE();
}
}
if(EG(active_namespace) != EG(global_namespace_ptr)) {
/* if we are not global, go find in local constant table */
if (zend_hash_find(&EG(active_namespace)->constants_table, EX(opline)->op2.u.constant.value.str.val, EX(opline)->op2.u.constant.value.str.len+1, (void **) &value) == SUCCESS) {
zval_update_constant(value, (void *) 1 TSRMLS_CC);
EX_T(EX(opline)->result.u.var).tmp_var = **value;
zval_copy_ctor(&EX_T(EX(opline)->result.u.var).tmp_var);
NEXT_OPCODE();
}
}
if (!zend_get_constant(EX(opline)->op2.u.constant.value.str.val, EX(opline)->op2.u.constant.value.str.len, &EX_T(EX(opline)->result.u.var).tmp_var TSRMLS_CC)) {
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
EX(opline)->op2.u.constant.value.str.val,
@ -3201,16 +3159,6 @@ int zend_fetch_constant_handler(ZEND_OPCODE_HANDLER_ARGS)
ce = EX_T(EX(opline)->op1.u.var).EA.class_entry;
if (&ce->constants_table == &EG(global_namespace_ptr)->constants_table) {
if (!zend_get_constant(EX(opline)->op2.u.constant.value.str.val, EX(opline)->op2.u.constant.value.str.len, &EX_T(EX(opline)->result.u.var).tmp_var TSRMLS_CC)) {
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
EX(opline)->op2.u.constant.value.str.val,
EX(opline)->op2.u.constant.value.str.val);
EX_T(EX(opline)->result.u.var).tmp_var = EX(opline)->op2.u.constant;
zval_copy_ctor(&EX_T(EX(opline)->result.u.var).tmp_var);
}
NEXT_OPCODE();
}
if (zend_hash_find(&ce->constants_table, EX(opline)->op2.u.constant.value.str.val, EX(opline)->op2.u.constant.value.str.len+1, (void **) &value) == SUCCESS) {
zval_update_constant(value, (void *) 1 TSRMLS_CC);
EX_T(EX(opline)->result.u.var).tmp_var = **value;
@ -3380,7 +3328,6 @@ int zend_include_or_eval_handler(ZEND_OPCODE_HANDLER_ARGS)
}
if (zend_hash_add(&EG(included_files), file_handle.opened_path, strlen(file_handle.opened_path)+1, (void *)&dummy, sizeof(int), NULL)==SUCCESS) {
CG(active_namespace) = EG(global_namespace_ptr);
new_op_array = zend_compile_file(&file_handle, (EX(opline)->op2.u.constant.value.lval==ZEND_INCLUDE_ONCE?ZEND_INCLUDE:ZEND_REQUIRE) TSRMLS_CC);
zend_destroy_file_handle(&file_handle TSRMLS_CC);
} else {
@ -3399,13 +3346,11 @@ int zend_include_or_eval_handler(ZEND_OPCODE_HANDLER_ARGS)
break;
case ZEND_INCLUDE:
case ZEND_REQUIRE:
CG(active_namespace) = EG(global_namespace_ptr);
new_op_array = compile_filename(EX(opline)->op2.u.constant.value.lval, inc_filename TSRMLS_CC);
break;
case ZEND_EVAL: {
char *eval_desc = zend_make_compiled_string_description("eval()'d code" TSRMLS_CC);
CG(active_namespace) = EG(global_namespace_ptr);
new_op_array = compile_string(inc_filename, eval_desc TSRMLS_CC);
efree(eval_desc);
}
@ -3420,7 +3365,6 @@ int zend_include_or_eval_handler(ZEND_OPCODE_HANDLER_ARGS)
if (new_op_array) {
zval *saved_object;
zend_function *saved_function;
zend_namespace *active_namespace = EG(active_namespace);
EG(return_value_ptr_ptr) = EX_T(EX(opline)->result.u.var).var.ptr_ptr;
EG(active_op_array) = new_op_array;
@ -3431,12 +3375,9 @@ int zend_include_or_eval_handler(ZEND_OPCODE_HANDLER_ARGS)
EX(function_state).function = (zend_function *) new_op_array;
EX(object) = NULL;
zend_switch_namespace(EG(global_namespace_ptr) TSRMLS_CC);
zend_execute(new_op_array TSRMLS_CC);
zend_switch_namespace(active_namespace TSRMLS_CC);
EX(function_state).function = saved_function;
EX(object) = saved_object;
@ -3967,31 +3908,6 @@ int zend_nop_handler(ZEND_OPCODE_HANDLER_ARGS)
NEXT_OPCODE();
}
int zend_start_namespace_handler(ZEND_OPCODE_HANDLER_ARGS)
{
zval *namespace_name;
zend_namespace **pns;
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_USER_NAMESPACE) {
zend_error(E_ERROR, "Internal error: Cannot locate namespace '%s'", Z_STRVAL_P(namespace_name));
}
} else {
pns = &EG(global_namespace_ptr);
}
if(EG(active_namespace) != *pns) {
zend_switch_namespace(*pns TSRMLS_CC);
}
NEXT_OPCODE();
}
int zend_add_interface_handler(ZEND_OPCODE_HANDLER_ARGS)
{
zend_class_entry *ce = EX_T(EX(opline)->op1.u.var).EA.class_entry;
@ -4251,7 +4167,6 @@ 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_START_NAMESPACE] = zend_start_namespace_handler;
zend_opcode_handlers[ZEND_ADD_INTERFACE] = zend_add_interface_handler;
zend_opcode_handlers[ZEND_VERIFY_INSTANCEOF] = zend_verify_instanceof_handler;

1
Zend/zend_execute.h

@ -70,7 +70,6 @@ static inline void safe_free_zval_ptr(zval *p)
ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***ce TSRMLS_DC);
ZEND_API int zend_lookup_ns_class(char *name, int name_length, zend_class_entry ***ce TSRMLS_DC);
ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC);
void zend_switch_namespace(zend_namespace *ns TSRMLS_DC);
static inline int i_zend_is_true(zval *op)
{

56
Zend/zend_execute_API.c

@ -177,10 +177,6 @@ void init_executor(TSRMLS_D)
EG(exception) = NULL;
EG(scope) = NULL;
EG(active_namespace) = &CG(global_namespace);
EG(global_namespace_ptr) = &CG(global_namespace);
CG(global_namespace).static_members = &EG(symbol_table);
EG(current_execute_data) = NULL;
@ -192,11 +188,6 @@ void init_executor(TSRMLS_D)
void shutdown_executor(TSRMLS_D)
{
/* return to global namespace here */
if(EG(active_namespace) != EG(global_namespace_ptr)) {
zend_switch_namespace(EG(global_namespace_ptr) TSRMLS_CC);
}
zend_try {
zend_ptr_stack_destroy(&EG(arg_types_stack));
@ -544,7 +535,6 @@ int fast_call_user_function(HashTable *function_table, zval **object_pp, zval *f
zend_class_entry *calling_scope = NULL;
char *function_name_lc;
zval *current_this;
zend_namespace *current_namespace = EG(active_namespace);
zend_execute_data execute_data;
/* Initialize execute_data */
@ -727,7 +717,6 @@ int fast_call_user_function(HashTable *function_table, zval **object_pp, zval *f
}
zend_ptr_stack_clear_multiple(TSRMLS_C);
EG(function_state_ptr) = original_function_state_ptr;
EG(active_namespace) = current_namespace;
if (EG(This)) {
zval_ptr_dtor(&EG(This));
@ -777,40 +766,6 @@ ZEND_API int zend_lookup_class(char *name, int name_length, zend_class_entry ***
return zend_hash_find(EG(class_table), name, name_length + 1, (void **) ce);
}
ZEND_API int zend_lookup_ns_class(char *name, int name_length, zend_class_entry ***ce TSRMLS_DC)
{
char *ns_name;
char *class_name;
char *name_end = name + name_length;
int ns_name_length;
zend_namespace **ns;
/* handle simple class name case */
if ((class_name = zend_memnstr(name, "::", sizeof("::")-1, name_end)) == NULL) {
return zend_lookup_class(name, name_length, ce TSRMLS_CC);
}
/* handle ::C case */
if (class_name == name) {
return zend_lookup_class(name + sizeof("::")-1, name_length - sizeof("::")+1, ce TSRMLS_CC);
}
ns_name_length = class_name - name;
class_name += sizeof("::")-1;
if (class_name == name_end) {
return FAILURE;
}
ns_name = zend_strndup(name, ns_name_length);
if (zend_hash_find(&EG(global_namespace_ptr)->class_table, ns_name, ns_name_length+1, (void **)&ns) == SUCCESS && CLASS_IS_NAMESPACE(*ns) &&
zend_hash_find(&(*ns)->class_table, class_name, name_end - class_name + 1, (void **)ce) == SUCCESS) {
free(ns_name);
return SUCCESS;
}
free(ns_name);
return FAILURE;
}
ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC)
{
zval pv;
@ -1086,17 +1041,6 @@ void zend_unset_timeout(TSRMLS_D)
#endif
}
void zend_switch_namespace(zend_namespace *ns TSRMLS_DC)
{
if(NULL == ns) {
return;
}
EG(active_namespace) = ns;
EG(function_table) = &ns->function_table;
EG(class_table) = &ns->class_table;
/* EG(zend_constants) = &ns->constants_table; */
}
/*
* Local variables:
* tab-width: 4

6
Zend/zend_globals.h

@ -70,7 +70,6 @@ struct _zend_compiler_globals {
zend_stack declare_stack;
zend_class_entry *active_class_entry;
zend_namespace *active_namespace;
/* variables for list() compilation */
zend_llist list_llist;
@ -88,11 +87,8 @@ struct _zend_compiler_globals {
zend_op_array *active_op_array;
zend_namespace global_namespace;
HashTable *function_table; /* function symbol table */
HashTable *class_table; /* class table */
HashTable namespace_table; /* namespaces */
HashTable filenames_table;
@ -173,8 +169,6 @@ struct _zend_executor_globals {
HashTable *zend_constants; /* constants table */
zend_class_entry *scope;
zend_namespace *global_namespace_ptr;
zend_namespace *active_namespace;
zval *This;

94
Zend/zend_language_parser.y

@ -129,7 +129,6 @@
%token T_FUNC_C
%token T_LINE
%token T_FILE
%token T_NAMESPACE_C
%token T_COMMENT
%token T_DOC_COMMENT
%token T_OPEN_TAG
@ -141,9 +140,6 @@
%token T_DOLLAR_OPEN_CURLY_BRACES
%token T_CURLY_OPEN
%token T_PAAMAYIM_NEKUDOTAYIM
%token T_IMPORT T_FROM
%token T_NAMESPACE_NAME
%token T_NAMESPACE
%% /* Rules */
@ -161,7 +157,6 @@ top_statement:
statement
| function_declaration_statement { zend_do_early_binding(TSRMLS_C); }
| class_declaration_statement
| namespace_declaration_statement
;
@ -220,29 +215,9 @@ unticked_statement:
T_CATCH '(' fully_qualified_class_name T_VARIABLE ')' { zend_do_begin_catch(&$1, &$8, &$9, 1 TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
additional_catches
| T_THROW expr ';' { zend_do_throw(&$2 TSRMLS_CC); }
| T_IMPORT { zend_do_begin_import(TSRMLS_C); } import_rule T_FROM import_namespace { zend_do_end_import(&$5 TSRMLS_CC); } ';'
;
import_rule:
'*' { zend_do_import(T_FUNCTION, NULL TSRMLS_CC); zend_do_import(T_CLASS, NULL TSRMLS_CC); zend_do_import(T_CONST, NULL TSRMLS_CC); }
| import_commands
;
import_commands:
import_commands ',' import_command
| import_command
;
import_command:
T_FUNCTION T_STRING { zend_do_import(T_FUNCTION, &$2 TSRMLS_CC); }
| T_CLASS T_STRING { zend_do_import(T_CLASS, &$2 TSRMLS_CC); }
| T_CONST T_STRING { zend_do_import(T_CONST, &$2 TSRMLS_CC); }
| T_FUNCTION '*' { zend_do_import(T_FUNCTION, NULL TSRMLS_CC); }
| T_CLASS '*' { zend_do_import(T_CLASS, NULL TSRMLS_CC); }
| T_CONST '*' { zend_do_import(T_CONST, NULL TSRMLS_CC); }
;
additional_catches:
non_empty_additional_catches
| /* empty */
@ -305,37 +280,6 @@ class_entry_type:
| T_INTERFACE { $$.u.constant.value.lval = ZEND_ACC_INTERFACE; }
;
namespace_declaration_statement:
T_NAMESPACE namespace_name '{' { zend_do_begin_namespace(&$1, &$2 TSRMLS_CC); } namespace_statement_list '}' { zend_do_end_namespace(&$1 TSRMLS_CC); }
;
namespace_statement_list:
namespace_statement_list namespace_statement
| /* empty */
;
namespace_statement:
T_VAR namespace_var_declaration_list ';'
| namespace_const_declaration ';'
| function_declaration_statement
| class_declaration_statement
;
namespace_var_declaration_list:
namespace_var_declaration_list ',' namespace_var_declaration
| namespace_var_declaration
;
namespace_var_declaration:
T_VARIABLE { zend_do_declare_namespace_var(&$1, NULL TSRMLS_CC); }
| T_VARIABLE '=' static_scalar { zend_do_declare_namespace_var(&$1, &$3 TSRMLS_CC); }
;
namespace_const_declaration:
namespace_const_declaration ',' T_STRING '=' const_scalar_expr { zend_do_declare_namespace_constant(&$3, &$5 TSRMLS_CC); }
| T_CONST T_STRING '=' const_scalar_expr { zend_do_declare_namespace_constant(&$2, &$4 TSRMLS_CC); }
;
extends_from:
/* empty */ { $$.op_type = IS_UNUSED; }
| T_EXTENDS fully_qualified_class_name { $$ = $2; }
@ -640,7 +584,7 @@ function_call:
T_STRING '(' { $2.u.opline_num = zend_do_begin_function_call(&$1 TSRMLS_CC); }
function_call_parameter_list
')' { zend_do_end_function_call(&$1, &$$, &$4, 0, $2.u.opline_num TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C); }
| class_or_namespace_constant '(' { zend_do_begin_class_member_function_call(TSRMLS_C); zend_do_extended_fcall_begin(TSRMLS_C); }
| class_constant '(' { zend_do_begin_class_member_function_call(TSRMLS_C); zend_do_extended_fcall_begin(TSRMLS_C); }
function_call_parameter_list
')' { zend_do_end_function_call(NULL, &$$, &$4, 1, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
| variable_without_objects '(' { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_dynamic_function_call(&$1 TSRMLS_CC); }
@ -649,27 +593,13 @@ function_call:
;
fully_qualified_class_name:
namespace_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_class(&$$, &$1, &$3, 0 TSRMLS_CC); }
| T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_class(&$$, NULL, &$2, 1 TSRMLS_CC); }
| T_STRING { zend_do_fetch_class(&$$, NULL, &$1, 0 TSRMLS_CC); }
;
import_namespace:
T_NAMESPACE_NAME { zend_do_fetch_class(&$$, NULL, &$1, 0 TSRMLS_CC); }
| T_STRING { zend_do_fetch_class(&$$, NULL, &$1, 0 TSRMLS_CC); }
T_STRING { zend_do_fetch_class(&$$, &$1 TSRMLS_CC); }
;
dynamic_class_name:
namespace_name T_PAAMAYIM_NEKUDOTAYIM static_or_variable_string { zend_do_fetch_class(&$$, &$1, &$3, 0 TSRMLS_CC); }
| T_PAAMAYIM_NEKUDOTAYIM static_or_variable_string { zend_do_fetch_class(&$$, NULL, &$2, 1 TSRMLS_CC); }
| static_or_variable_string { zend_do_fetch_class(&$$, NULL, &$1, 0 TSRMLS_CC); }
static_or_variable_string { zend_do_fetch_class(&$$, &$1 TSRMLS_CC); }
;
namespace_name:
T_NAMESPACE_NAME { $$ = $1; }
| T_STRING { $$ = $1; }
;
static_or_variable_string:
T_STRING { $$ = $1; }
| r_variable_without_static_member { $$ = $1; }
@ -697,7 +627,6 @@ common_scalar:
| T_FILE { $$ = $1; }
| T_CLASS_C { $$ = $1; }
| T_FUNC_C { $$ = $1; }
| T_NAMESPACE_C { $$ = $1; }
;
@ -729,7 +658,7 @@ const_scalar:
| '+' const_scalar { $$ = $2; }
| '-' const_scalar { zval minus_one; minus_one.type = IS_LONG; minus_one.value.lval = -1; mul_function(&$2.u.constant, &$2.u.constant, &minus_one TSRMLS_CC); $$ = $2; }
| T_ARRAY '(' static_array_pair_list ')' { $$ = $3; $$.u.constant.type = IS_CONSTANT_ARRAY; }
| class_or_namespace_constant { /* FIXME */ }
| class_constant { /* FIXME */ }
;
static_scalar: /* compile-time evaluated scalars */
@ -738,13 +667,13 @@ static_scalar: /* compile-time evaluated scalars */
| '+' static_scalar { $$ = $2; }
| '-' static_scalar { zval minus_one; minus_one.type = IS_LONG; minus_one.value.lval = -1; mul_function(&$2.u.constant, &$2.u.constant, &minus_one TSRMLS_CC); $$ = $2; }
| T_ARRAY '(' static_array_pair_list ')' { $$ = $3; $$.u.constant.type = IS_CONSTANT_ARRAY; }
| class_or_namespace_constant { /* FIXME */ }
| class_constant { /* FIXME */ }
;
scalar:
T_STRING { zend_do_fetch_constant(&$$, NULL, &$1, ZEND_RT TSRMLS_CC); }
| T_STRING_VARNAME { $$ = $1; }
| class_or_namespace_constant { $$ = $1; }
| class_constant { $$ = $1; }
| common_scalar { $$ = $1; }
| '"' encaps_list '"' { $$ = $2; }
| '\'' encaps_list '\'' { $$ = $2; }
@ -826,9 +755,7 @@ variable_without_objects:
;
static_member:
T_PAAMAYIM_NEKUDOTAYIM T_STRING T_PAAMAYIM_NEKUDOTAYIM variable_without_objects { $$ = $4; zend_do_fetch_class(&$1, NULL, &$2, 1 TSRMLS_CC); zend_do_fetch_static_member(&$1 TSRMLS_CC); }
| namespace_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects { $$ = $3; zend_do_fetch_class(&$2, NULL, &$1, 0 TSRMLS_CC); zend_do_fetch_static_member(&$2 TSRMLS_CC); }
| namespace_name T_PAAMAYIM_NEKUDOTAYIM T_STRING T_PAAMAYIM_NEKUDOTAYIM variable_without_objects { $$ = $5; zend_do_fetch_class(&$4, &$1, &$3, 0 TSRMLS_CC); zend_do_fetch_static_member(&$4 TSRMLS_CC); }
fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects { $$ = $3; zend_do_fetch_static_member(&$1 TSRMLS_CC); }
;
@ -957,11 +884,8 @@ isset_variables:
| isset_variables ',' { zend_do_boolean_and_begin(&$1, &$2 TSRMLS_CC); } variable { znode tmp; zend_do_isset_or_isempty(ZEND_ISSET, &tmp, &$4 TSRMLS_CC); zend_do_boolean_and_end(&$$, &$1, &tmp, &$2 TSRMLS_CC); }
;
class_or_namespace_constant:
T_PAAMAYIM_NEKUDOTAYIM namespace_name { zend_do_fetch_constant(&$$, NULL, &$2, ZEND_RT TSRMLS_CC); }
| T_PAAMAYIM_NEKUDOTAYIM T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_class(&$1, NULL, &$2, 1 TSRMLS_CC); zend_do_fetch_constant(&$$, &$1, &$4, ZEND_RT TSRMLS_CC); }
| namespace_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_class(&$2, NULL, &$1, 0 TSRMLS_CC); zend_do_fetch_constant(&$$, &$2, &$3, ZEND_RT TSRMLS_CC); }
| namespace_name T_PAAMAYIM_NEKUDOTAYIM T_STRING T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_class(&$4, &$1, &$3, 0 TSRMLS_CC); zend_do_fetch_constant(&$$, &$4, &$5, ZEND_RT TSRMLS_CC); }
class_constant:
fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM T_STRING { zend_do_fetch_constant(&$$, &$1, &$3, ZEND_RT TSRMLS_CC); }
;
%%

46
Zend/zend_language_scanner.l

@ -292,7 +292,6 @@ ZEND_API zend_op_array *compile_file(zend_file_handle *file_handle, int type TSR
init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
CG(in_compilation) = 1;
CG(active_op_array) = op_array;
op_array->ns = CG(active_namespace);
compiler_result = zendparse(TSRMLS_C);
zend_do_return(&retval_znode, 0 TSRMLS_CC);
CG(in_compilation) = original_in_compilation;
@ -406,7 +405,6 @@ zend_op_array *compile_string(zval *source_string, char *filename TSRMLS_DC)
} else {
init_op_array(op_array, ZEND_EVAL_CODE, INITIAL_OP_ARRAY_SIZE TSRMLS_CC);
CG(active_op_array) = op_array;
op_array->ns = CG(active_namespace);
BEGIN(ST_IN_SCRIPTING);
compiler_result = zendparse(TSRMLS_C);
@ -481,7 +479,6 @@ ENCAPSED_TOKENS [\[\]{}$]
ESCAPED_AND_WHITESPACE [\n\t\r #'.:;,()|^&+-/*=%!~<>?@]+
ANY_CHAR (.|[\n])
NEWLINE ("\r"|"\n"|"\r\n")
NAMESPACE_NAME ({LABEL}":")+{LABEL}
%option noyylineno
%option noyywrap
@ -627,10 +624,6 @@ NAMESPACE_NAME ({LABEL}":")+{LABEL}
return T_IMPLEMENTS;
}
<ST_IN_SCRIPTING>"namespace" {
return T_NAMESPACE;
}
<ST_IN_SCRIPTING,ST_DOUBLE_QUOTES,ST_BACKQUOTE,ST_HEREDOC>"->" {
yy_push_state(ST_LOOKING_FOR_PROPERTY TSRMLS_CC);
return T_OBJECT_OPERATOR;
@ -697,14 +690,6 @@ NAMESPACE_NAME ({LABEL}":")+{LABEL}
return T_INCLUDE;
}
<ST_IN_SCRIPTING>"import" {
return T_IMPORT;
}
<ST_IN_SCRIPTING>"from" {
return T_FROM;
}
<ST_IN_SCRIPTING>"include_once" {
return T_INCLUDE_ONCE;
}
@ -999,14 +984,10 @@ NAMESPACE_NAME ({LABEL}":")+{LABEL}
}
<ST_IN_SCRIPTING>"__METHOD__" {
char *namespace_name = CG(active_namespace)->name;
char *class_name = CG(active_class_entry) ? CG(active_class_entry)->name : NULL;
char *func_name = CG(active_op_array)->function_name;
size_t len = 0;
if (namespace_name) {
len += strlen(namespace_name) + 2;
}
if (class_name) {
len += strlen(class_name) + 2;
}
@ -1014,10 +995,8 @@ NAMESPACE_NAME ({LABEL}":")+{LABEL}
len += strlen(func_name);
}
zendlval->value.str.val = emalloc(len + 1);
zendlval->value.str.len = sprintf(zendlval->value.str.val, "%s%s%s%s%s",
namespace_name ? namespace_name : "",
namespace_name && (class_name || func_name) ? "::" : "",
zendlval->value.str.val = emalloc(len+1);
zendlval->value.str.len = sprintf(zendlval->value.str.val, "%s%s%s",
class_name ? class_name : "",
class_name && func_name ? "::" : "",
func_name ? func_name : ""
@ -1045,20 +1024,6 @@ NAMESPACE_NAME ({LABEL}":")+{LABEL}
return T_FILE;
}
<ST_IN_SCRIPTING>"__NAMESPACE__" {
char *ns_name;
if(CG(active_namespace) == &CG(global_namespace)) {
ns_name = "";
} else {
ns_name = CG(active_namespace)->name;
}
zendlval->value.str.len = strlen(ns_name);
zendlval->value.str.val = estrndup(ns_name, zendlval->value.str.len);
zendlval->type = IS_STRING;
return T_NAMESPACE_C;
}
<INITIAL>(([^<]|"<"[^?%s<]){1,400})|"<s"|"<" {
zendlval->value.str.val = (char *) estrndup(yytext, yyleng);
zendlval->value.str.len = yyleng;
@ -1149,13 +1114,6 @@ NAMESPACE_NAME ({LABEL}":")+{LABEL}
return T_STRING;
}
<ST_IN_SCRIPTING>{NAMESPACE_NAME} {
zendlval->value.str.val = (char *)estrndup(yytext, yyleng);
zendlval->value.str.len = yyleng;
zendlval->type = IS_STRING;
return T_NAMESPACE_NAME;
}
<ST_DOUBLE_QUOTES,ST_BACKQUOTE,ST_HEREDOC>{LABEL} {
zendlval->value.str.val = (char *)estrndup(yytext, yyleng);
zendlval->value.str.len = yyleng;

36
Zend/zend_object_handlers.c

@ -651,32 +651,28 @@ zval **zend_std_get_static_property(zend_class_entry *ce, char *property_name, i
zend_property_info *property_info;
zend_property_info std_property_info;
if (ce->type == ZEND_USER_NAMESPACE || ce->type == ZEND_INTERNAL_NAMESPACE) {
zend_hash_find(ce->static_members, property_name, property_name_len+1, (void **) &retval);
} else {
if (zend_hash_find(&ce->properties_info, property_name, property_name_len+1, (void **) &property_info)==FAILURE) {
std_property_info.flags = ZEND_ACC_PUBLIC;
std_property_info.name = property_name;
std_property_info.name_length = property_name_len;
std_property_info.h = zend_get_hash_value(std_property_info.name, std_property_info.name_length+1);
property_info = &std_property_info;
}
if (zend_hash_find(&ce->properties_info, property_name, property_name_len+1, (void **) &property_info)==FAILURE) {
std_property_info.flags = ZEND_ACC_PUBLIC;
std_property_info.name = property_name;
std_property_info.name_length = property_name_len;
std_property_info.h = zend_get_hash_value(std_property_info.name, std_property_info.name_length+1);
property_info = &std_property_info;
}
#if 1&&DEBUG_OBJECT_HANDLERS
zend_printf("Access type for %s::%s is %s\n", ce->name, property_name, zend_visibility_string(property_info->flags));
zend_printf("Access type for %s::%s is %s\n", ce->name, property_name, zend_visibility_string(property_info->flags));
#endif
if (!zend_verify_property_access(property_info, ce TSRMLS_CC)) {
zend_error(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ce->name, property_name);
}
if (!zend_verify_property_access(property_info, ce TSRMLS_CC)) {
zend_error(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ce->name, property_name);
}
while (tmp_ce) {
if (zend_hash_quick_find(tmp_ce->static_members, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval)==SUCCESS) {
statics_table = tmp_ce->static_members;
break;
}
tmp_ce = tmp_ce->parent;
while (tmp_ce) {
if (zend_hash_quick_find(tmp_ce->static_members, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval)==SUCCESS) {
statics_table = tmp_ce->static_members;
break;
}
tmp_ce = tmp_ce->parent;
}
if (!retval) {

34
Zend/zend_opcode.c

@ -80,7 +80,6 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz
op_array->arg_types = NULL;
op_array->scope = NULL;
op_array->ns = NULL;
op_array->brk_cont_array = NULL;
op_array->last_brk_cont = 0;
@ -181,39 +180,6 @@ ZEND_API void destroy_zend_class(zend_class_entry **pce)
}
free(ce);
break;
case ZEND_USER_NAMESPACE:
case ZEND_INTERNAL_NAMESPACE:
destroy_zend_namespace(pce);
break;
}
}
ZEND_API void destroy_zend_namespace(zend_namespace **pns)
{
zend_namespace *ns = *pns;
switch (ns->type) {
case ZEND_USER_NAMESPACE:
zend_hash_destroy(&ns->function_table);
zend_hash_destroy(&ns->class_table);
zend_hash_destroy(&ns->constants_table);
zend_hash_destroy(ns->static_members);
FREE_HASHTABLE(ns->static_members);
if (ns->doc_comment) {
efree(ns->doc_comment);
}
efree(ns->name);
efree(ns);
break;
case ZEND_INTERNAL_NAMESPACE:
zend_hash_destroy(&ns->function_table);
zend_hash_destroy(&ns->class_table);
zend_hash_destroy(&ns->constants_table);
zend_hash_destroy(ns->static_members);
free(ns->static_members);
free(ns->name);
free(ns);
break;
}
}

Loading…
Cancel
Save