]> granicus.if.org Git - php/commitdiff
Added namespace related optimizations and comments
authorDmitry Stogov <dmitry@php.net>
Mon, 20 Aug 2007 09:48:41 +0000 (09:48 +0000)
committerDmitry Stogov <dmitry@php.net>
Mon, 20 Aug 2007 09:48:41 +0000 (09:48 +0000)
Zend/zend_API.c
Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_execute_API.c
Zend/zend_language_parser.y

index dc55fec38d7cac7bf8693169bed8cb0957a6cae2..727621bc1111eb5b8face6d5f8279f1d6354cecd 100644 (file)
@@ -801,7 +801,7 @@ static char *zend_parse_arg_impl(int arg_num, zval **arg, va_list *va, char **sp
                                        fci->size = 0;
                                        fcc->initialized = 0;
                                        break;
-                               } 
+                               }
 
                                if (zend_fcall_info_init(*arg, fci, fcc, NULL TSRMLS_CC) == SUCCESS) {
                                        break;
@@ -1001,7 +1001,7 @@ static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int fl
                                        break;
                        }
                }
-               
+
                if (T_arg_type == -1) {
                        T_arg_type = ZEND_STR_TYPE;
                }
@@ -1070,7 +1070,7 @@ static int zend_parse_va_args(int num_args, char *type_spec, va_list *va, int fl
                                   get_active_function_name(TSRMLS_C), __num_args); \
         return FAILURE; \
     }\
-}    
+}
 
 ZEND_API int zend_parse_parameters_ex(int flags, int num_args TSRMLS_DC, char *type_spec, ...) /* {{{ */
 {
@@ -2084,7 +2084,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, zend_function_entr
                        if (UG(unicode)) {
                                zend_arg_info *args;
                                int n = ptr->num_args;
-                               
+
                                args = internal_function->arg_info = malloc((n + 1) * sizeof(zend_arg_info));
                                memcpy(args, ptr->arg_info+1, (n + 1) * sizeof(zend_arg_info));
                                while (n > 0) {
@@ -2175,7 +2175,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, zend_function_entr
                         */
                        unsigned int lc_func_name_len;
                        zstr lc_func_name = zend_u_str_case_fold(ZEND_STR_TYPE, internal_function->function_name, fname_len, 0, &lc_func_name_len);
-                       
+
                        if ((lc_func_name_len == lc_class_name_len) && !memcmp(lc_func_name.v, lc_class_name.v, UG(unicode)?UBYTES(lc_class_name_len):lc_class_name_len) && !ctor) {
                                ctor = reg_function;
                        } else if ((fname_len == sizeof(ZEND_CONSTRUCTOR_FUNC_NAME)-1) && !memcmp(lowercase_name, ZEND_CONSTRUCTOR_FUNC_NAME, sizeof(ZEND_CONSTRUCTOR_FUNC_NAME))) {
@@ -2368,7 +2368,7 @@ void module_destructor(zend_module_entry *module) /* {{{ */
                module->module_shutdown_func(module->type, module->module_number TSRMLS_CC);
        }
 
-       
+
        /* Deinitilaise module globals */
        if (module->globals_size) {
 #ifdef ZTS
@@ -2498,7 +2498,7 @@ ZEND_API void zend_class_implements(zend_class_entry *class_entry TSRMLS_DC, int
                interface_entry = va_arg(interface_list, zend_class_entry *);
                zend_do_implement_interface(class_entry, interface_entry TSRMLS_CC);
        }
-       
+
        va_end(interface_list);
 }
 /* }}} */
@@ -2607,6 +2607,7 @@ static int zend_is_callable_check_func(int check_flags, zval ***zobj_ptr_ptr, ze
        *fptr_ptr = NULL;
 
        if (!ce_org) {
+               /* Skip leading :: */
                if (Z_TYPE_P(callable) == IS_UNICODE &&
                    Z_USTRVAL_P(callable)[0] == ':' &&
                    Z_USTRVAL_P(callable)[1] == ':') {
@@ -2624,6 +2625,8 @@ static int zend_is_callable_check_func(int check_flags, zval ***zobj_ptr_ptr, ze
                } else {
                        lmname = zend_u_str_case_fold(Z_TYPE_P(callable), Z_UNIVAL_P(callable), Z_UNILEN_P(callable), 1, &mlen);
                }
+               /* Check if function with given name exists.
+                  This may be a compound name that includes namespace name */
                if (zend_u_hash_find(EG(function_table), Z_TYPE_P(callable), lmname, mlen+1, (void**)&fptr) == SUCCESS) {
                        *fptr_ptr = fptr;
                        efree(lmname.v);
@@ -2631,6 +2634,7 @@ static int zend_is_callable_check_func(int check_flags, zval ***zobj_ptr_ptr, ze
                }
                efree(lmname.v);
        }
+       /* Split name into class/namespace and method/function names */
        if (Z_TYPE_P(callable) == IS_UNICODE) {
                if ((colon.u = u_strrstr(Z_USTRVAL_P(callable), u_doublecolon)) != NULL) {
                        mlen = u_strlen(colon.u+2);
@@ -2648,6 +2652,8 @@ static int zend_is_callable_check_func(int check_flags, zval ***zobj_ptr_ptr, ze
                }
        }
        if (colon.v != NULL) {
+               /* This is a compound name.
+                  Try to fetch class and then find static method. */
                *ce_ptr = zend_u_fetch_class(Z_TYPE_P(callable), Z_UNIVAL_P(callable), clen, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
                if (!*ce_ptr) {
                        return 0;
@@ -2657,14 +2663,14 @@ static int zend_is_callable_check_func(int check_flags, zval ***zobj_ptr_ptr, ze
                        return 0;
                }
                lmname = zend_u_str_case_fold(Z_TYPE_P(callable), mname, mlen, 1, &mlen);
-       } else {
+       } else if (ce_org) {
+               /* Try to fetch find static method of given class. */
                lmname = zend_u_str_case_fold(Z_TYPE_P(callable), Z_UNIVAL_P(callable), Z_UNILEN_P(callable), 1, &mlen);
-               if (ce_org) {
-                       ftable = &ce_org->function_table;
-                       *ce_ptr = ce_org;
-               } else {
-                       ftable = EG(function_table);
-               }
+               ftable = &ce_org->function_table;
+               *ce_ptr = ce_org;
+       } else {
+               /* We already checked for plain function before. */
+               return 0;
        }
 
        retval = zend_u_hash_find(ftable, Z_TYPE_P(callable), lmname, mlen+1, (void**)&fptr) == SUCCESS ? 1 : 0;
@@ -2968,7 +2974,7 @@ ZEND_API int zend_fcall_info_init(zval *callable, zend_fcall_info *fci, zend_fca
        fci->symbol_table = NULL;
 
        if (ZEND_U_CASE_EQUAL(ZEND_STR_TYPE, func->common.function_name, USTR_LEN(func->common.function_name), ZEND_CALL_FUNC_NAME, sizeof(ZEND_CALL_FUNC_NAME)-1) ||
-           ZEND_U_CASE_EQUAL(ZEND_STR_TYPE, func->common.function_name, USTR_LEN(func->common.function_name), ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1)) { 
+           ZEND_U_CASE_EQUAL(ZEND_STR_TYPE, func->common.function_name, USTR_LEN(func->common.function_name), ZEND_CALLSTATIC_FUNC_NAME, sizeof(ZEND_CALLSTATIC_FUNC_NAME)-1)) {
                fcc->initialized = 0;
                fcc->function_handler = NULL;
                fcc->calling_scope = NULL;
@@ -3048,13 +3054,13 @@ ZEND_API int zend_fcall_info_args(zend_fcall_info *fci, zval *args TSRMLS_DC) /*
 ZEND_API int zend_fcall_info_argp(zend_fcall_info *fci TSRMLS_DC, int argc, zval ***argv) /* {{{ */
 {
        int i;
-       
+
        if (argc < 0) {
                return FAILURE;
        }
-       
+
        zend_fcall_info_args_clear(fci, !argc);
-       
+
        if (argc) {
                fci->param_count = argc;
                fci->params = (zval ***) erealloc(fci->params, fci->param_count * sizeof(zval **));
@@ -3064,7 +3070,7 @@ ZEND_API int zend_fcall_info_argp(zend_fcall_info *fci TSRMLS_DC, int argc, zval
                        fci->params[i] = argv[i];
                }
        }
-       
+
        return SUCCESS;
 }
 /* }}} */
@@ -3073,24 +3079,24 @@ ZEND_API int zend_fcall_info_argv(zend_fcall_info *fci TSRMLS_DC, int argc, va_l
 {
        int i;
        zval **arg;
-       
+
        if (argc < 0) {
                return FAILURE;
        }
-       
+
        zend_fcall_info_args_clear(fci, !argc);
-       
+
        if (argc) {
                fci->param_count = argc;
                fci->params = (zval ***) erealloc(fci->params, fci->param_count * sizeof(zval **));
-               
+
                for (i = 0; i < argc; ++i) {
                        arg = va_arg(*argv, zval **);
                        ZVAL_ADDREF(*arg);
                        fci->params[i] = arg;
                }
        }
-       
+
        return SUCCESS;
 }
 /* }}} */
@@ -3099,11 +3105,11 @@ ZEND_API int zend_fcall_info_argn(zend_fcall_info *fci TSRMLS_DC, int argc, ...)
 {
        int ret;
        va_list argv;
-       
+
        va_start(argv, argc);
        ret = zend_fcall_info_argv(fci TSRMLS_CC, argc, &argv);
        va_end(argv);
-       
+
        return ret;
 }
 /* }}} */
@@ -3119,7 +3125,7 @@ ZEND_API int zend_fcall_info_call(zend_fcall_info *fci, zend_fcall_info_cache *f
                zend_fcall_info_args(fci, args TSRMLS_CC);
        }
        result = zend_call_function(fci, fcc TSRMLS_CC);
-       
+
        if (!retval_ptr_ptr && retval) {
                zval_ptr_dtor(&retval);
        }
@@ -3439,7 +3445,7 @@ ZEND_API int zend_declare_class_constant_stringl(zend_class_entry *ce, char *nam
 {
        zval *constant;
 
-       if (ce->type & ZEND_INTERNAL_CLASS) {           
+       if (ce->type & ZEND_INTERNAL_CLASS) {
                constant = malloc(sizeof(zval));
                if (UG(unicode)) {
                        Z_TYPE_P(constant) = IS_UNICODE;
index 6e87c7ebc7e4696d6e44f9e80b2fbe20b78d06c7..08ea575851f1266f61eb18af6cd2e4148bc5680d 100644 (file)
@@ -1245,6 +1245,7 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
                zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
 
                if (CG(current_namespace)) {
+                       /* Prefix function name with current namespcae name */
                        znode tmp;
 
                        tmp.u.constant = *CG(current_namespace);
@@ -1451,8 +1452,11 @@ int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace
        zend_function *function;
        unsigned int lcname_len;
        zstr lcname;
+       int prefix_len = 0;
 
        if (check_namespace && CG(current_namespace)) {
+               /* We assume we call function from the current namespace
+                  if it is not prefixed. */
                znode tmp;
 
                tmp.op_type = IS_CONST;
@@ -1460,11 +1464,15 @@ int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace
                zval_copy_ctor(&tmp.u.constant);
                zend_do_build_namespace_name(&tmp, &tmp, function_name TSRMLS_CC);
                *function_name = tmp;
+
+               /* In run-time PHP will check for function with full name and
+                  internal function with short name */
+               prefix_len = Z_UNILEN_P(CG(current_namespace)) + 2;
        }
 
        lcname = zend_u_str_case_fold(Z_TYPE(function_name->u.constant), Z_UNIVAL(function_name->u.constant), Z_UNILEN(function_name->u.constant), 0, &lcname_len);
        if (zend_u_hash_find(CG(function_table), Z_TYPE(function_name->u.constant), lcname, lcname_len+1, (void **) &function)==FAILURE) {
-               zend_do_begin_dynamic_function_call(function_name TSRMLS_CC);
+               zend_do_begin_dynamic_function_call(function_name, prefix_len TSRMLS_CC);
                efree(lcname.v);
                return 1; /* Dynamic */
        }
@@ -1547,7 +1555,7 @@ void zend_do_clone(znode *result, znode *expr TSRMLS_DC) /* {{{ */
 }
 /* }}} */
 
-void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC) /* {{{ */
+void zend_do_begin_dynamic_function_call(znode *function_name, int prefix_len TSRMLS_DC) /* {{{ */
 {
        unsigned char *ptr = NULL;
        zend_op *opline;
@@ -1557,21 +1565,13 @@ void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC) /* {{{
        opline->op2 = *function_name;
        opline->extended_value = 0;
 
-       SET_UNUSED(opline->op1);
-       if (function_name->op_type == IS_CONST) {
-               if (Z_TYPE(function_name->u.constant) == IS_UNICODE) {
-                       UChar *p = u_memrchr(Z_USTRVAL(function_name->u.constant), ':', Z_USTRLEN(function_name->u.constant));
-                       if (p) {
-                               opline->op1.op_type = IS_CONST;
-                               ZVAL_LONG(&opline->op1.u.constant, p + 1 - Z_USTRVAL(function_name->u.constant));
-                       }                       
-               } else {
-                       char *p = zend_memrchr(Z_STRVAL(function_name->u.constant), ':', Z_STRLEN(function_name->u.constant));
-                       if (p) {
-                               opline->op1.op_type = IS_CONST;
-                               ZVAL_LONG(&opline->op1.u.constant, p + 1 - Z_STRVAL(function_name->u.constant));
-                       }                       
-               }
+       if (prefix_len) {
+               /* In run-time PHP will check for function with full name and
+                  internal function with short name */
+               opline->op1.op_type = IS_CONST;
+               ZVAL_LONG(&opline->op1.u.constant, prefix_len);
+       } else {
+               SET_UNUSED(opline->op1);
        }
 
        zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *));
@@ -1594,15 +1594,18 @@ void zend_resolve_class_name(znode *class_name, ulong *fetch_type, int check_ns_
                compound.s = memchr(Z_STRVAL(class_name->u.constant), ':', Z_STRLEN(class_name->u.constant));
        }
        if (compound.v) {
+               /* This is a compound class name that cotains namespace prefix */
                if (Z_TYPE(class_name->u.constant) == IS_UNICODE &&
                    Z_USTRVAL(class_name->u.constant)[0] == ':') {
+                   /* The unicode name has "::" prefix */
                    Z_USTRLEN(class_name->u.constant) -= 2;
                    memmove(Z_USTRVAL(class_name->u.constant), Z_USTRVAL(class_name->u.constant)+2, UBYTES(Z_USTRLEN(class_name->u.constant)+1));
                        Z_USTRVAL(class_name->u.constant) = eurealloc(
                                Z_USTRVAL(class_name->u.constant),
                                Z_USTRLEN(class_name->u.constant) + 1);
                } else if (Z_TYPE(class_name->u.constant) == IS_STRING &&
-                   Z_STRVAL(class_name->u.constant)[0] == ':') {
+                          Z_STRVAL(class_name->u.constant)[0] == ':') {
+                   /* The STRING name has "::" prefix */
                    Z_STRLEN(class_name->u.constant) -= 2;
                    memmove(Z_STRVAL(class_name->u.constant), Z_STRVAL(class_name->u.constant)+2, Z_STRLEN(class_name->u.constant)+1);
                        Z_STRVAL(class_name->u.constant) = erealloc(
@@ -1616,7 +1619,9 @@ void zend_resolve_class_name(znode *class_name, ulong *fetch_type, int check_ns_
                                len = compound.s - Z_STRVAL(class_name->u.constant);
                                lcname = zend_u_str_case_fold(Z_TYPE(class_name->u.constant), Z_UNIVAL(class_name->u.constant), len , 0, &lcname_len);
                        }
+                       /* Check if first part of compound name is an import name */
                        if (zend_u_hash_find(CG(current_import), Z_TYPE(class_name->u.constant), lcname, lcname_len+1, (void**)&ns) == SUCCESS) {
+                               /* Substitute import name */
                                tmp.op_type = IS_CONST;
                                tmp.u.constant = **ns;
                                zval_copy_ctor(&tmp.u.constant);
@@ -1631,12 +1636,14 @@ void zend_resolve_class_name(znode *class_name, ulong *fetch_type, int check_ns_
                                *class_name = tmp;
                        }
                        efree(lcname.v);
-               }       
+               }
        } else if (CG(current_import) || CG(current_namespace)) {
+               /* this is a plain name (without ::) */
                lcname = zend_u_str_case_fold(Z_TYPE(class_name->u.constant), Z_UNIVAL(class_name->u.constant), Z_UNILEN(class_name->u.constant), 0, &lcname_len);
 
                if (CG(current_import) &&
                    zend_u_hash_find(CG(current_import), Z_TYPE(class_name->u.constant), lcname, lcname_len+1, (void**)&ns) == SUCCESS) {
+                   /* The given name is an import name. Substitute it. */
                        zval_dtor(&class_name->u.constant);
                        class_name->u.constant = **ns;
                        zval_copy_ctor(&class_name->u.constant);
@@ -1649,6 +1656,9 @@ void zend_resolve_class_name(znode *class_name, ulong *fetch_type, int check_ns_
 
                                if (ns_lcname_len == lcname_len &&
                                    memcmp(lcname.v, ns_lcname.v, UG(unicode)?UBYTES(lcname_len):lcname_len) == 0) {
+                                   /* The given name is equal to name of current namespace.
+                                      PHP will need to perform additional cheks at run-time to
+                                      determine if we assume namespace or class name. */
                                        *fetch_type |= ZEND_FETCH_CLASS_RT_NS_NAME;
                                }
                                efree(ns_lcname.v);
@@ -1656,6 +1666,10 @@ void zend_resolve_class_name(znode *class_name, ulong *fetch_type, int check_ns_
 
                        if (zend_u_hash_find(CG(class_table), Z_TYPE(class_name->u.constant), lcname, lcname_len+1, (void**)&pce) == SUCCESS &&
                            (*pce)->type == ZEND_INTERNAL_CLASS) {
+                           /* There is an internal class with the same name exists.
+                              PHP will need to perform additional cheks at run-time to
+                              determine if we assume class in current namespace or
+                              internal one. */
                                *fetch_type |= ZEND_FETCH_CLASS_RT_NS_CHECK;
                        }
                        tmp.op_type = IS_CONST;
@@ -1741,7 +1755,7 @@ void zend_do_begin_class_member_function_call(znode *class_name, znode *method_n
        unsigned char *ptr = NULL;
        zend_op *opline;
        ulong fetch_type = 0;
-       
+
        if (method_name->op_type == IS_CONST) {
                zstr lcname;
                unsigned int lcname_len;
@@ -1777,7 +1791,8 @@ void zend_do_begin_class_member_function_call(znode *class_name, znode *method_n
 
        if (class_node.op_type == IS_CONST &&
                method_name->op_type == IS_CONST) {
-               /* Prebuild ns::func name to speedup run-time check */
+               /* Prebuild ns::func name to speedup run-time check.
+                  The additional names are stored in additional OP_DATA opcode. */
                zstr fname, lcname;
                unsigned int len, lcname_len;
 
@@ -1785,7 +1800,7 @@ void zend_do_begin_class_member_function_call(znode *class_name, znode *method_n
                opline->opcode = ZEND_OP_DATA;
                opline->op1.op_type = IS_CONST;
                SET_UNUSED(opline->op2);
-       
+
                len = Z_UNILEN(class_node.u.constant) + 2 + Z_UNILEN(method_name->u.constant);
                if (UG(unicode)) {
                        fname.u = eumalloc(len + 1);
@@ -1813,6 +1828,9 @@ void zend_do_begin_class_member_function_call(znode *class_name, znode *method_n
                efree(fname.v);
 
                if (fetch_type & ZEND_FETCH_CLASS_RT_NS_NAME) {
+                       /* Prebuild name without first part of compound name for cases
+                          when name is equal to current namespace name. This will speedup
+                          runtime check. */
                        zstr colon;
 
                        if (UG(unicode) && (colon.u = u_memchr(lcname.u, ':', lcname_len)) && colon.u[1] == ':') {
@@ -1823,7 +1841,7 @@ void zend_do_begin_class_member_function_call(znode *class_name, znode *method_n
                                colon.s += 2;
                                opline->op2.op_type = IS_CONST;
                                ZVAL_STRINGL(&opline->op2.u.constant, colon.s, lcname_len - (colon.s - lcname.s), 1);
-                       }                       
+                       }
                }
        }
 
@@ -2125,7 +2143,7 @@ void zend_do_begin_catch(znode *try_token, znode *class_name, znode *catch_var,
        znode catch_class;
 
        zend_do_fetch_class(&catch_class, class_name TSRMLS_CC);
-       
+
        catch_op_number = get_next_op_number(CG(active_op_array));
        if (catch_op_number > 0) {
                opline = &CG(active_op_array)->opcodes[catch_op_number-1];
@@ -3171,12 +3189,14 @@ void zend_do_begin_class_declaration(znode *class_token, znode *class_name, znod
                zend_error(E_COMPILE_ERROR, "Cannot use '%R' as class name as it is reserved", Z_TYPE(class_name->u.constant), Z_UNIVAL(class_name->u.constant));
        }
 
+       /* Class name must not conflict with import names */
        if (CG(current_import) &&
            zend_u_hash_exists(CG(current_import), Z_TYPE(class_name->u.constant), lcname, lcname_len+1)) {
                zend_error(E_COMPILE_ERROR, "Class name '%R' coflicts with import name", Z_TYPE(class_name->u.constant), Z_UNIVAL(class_name->u.constant));
        }
 
        if (CG(current_namespace)) {
+               /* Prefix class name with name of current namespace */
                znode tmp;
 
                tmp.u.constant = *CG(current_namespace);
@@ -3731,7 +3751,7 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con
 
                                if (constant_container) {
                                        zend_do_fetch_class(&class_node, constant_container TSRMLS_CC);
-                               }                               
+                               }
                                opline = get_next_op(CG(active_op_array) TSRMLS_CC);
                                opline->opcode = ZEND_FETCH_CONSTANT;
                                opline->result.op_type = IS_TMP_VAR;
@@ -4916,7 +4936,7 @@ void zend_release_labels(TSRMLS_D) /* {{{ */
 void zend_do_build_namespace_name(znode *result, znode *prefix, znode *name TSRMLS_DC) /* {{{ */
 {
        int len;
-       
+
        if (prefix) {
                *result = *prefix;
        } else {
@@ -4955,7 +4975,7 @@ void zend_do_namespace(znode *name TSRMLS_DC) /* {{{ */
                zend_error(E_COMPILE_ERROR, "Namespace declaration statement has to be the very first statement in the script");
        }
        if (CG(current_namespace)) {
-               zend_error(E_COMPILE_ERROR, "Namespace cannot be declared twice");              
+               zend_error(E_COMPILE_ERROR, "Namespace cannot be declared twice");
        }
        lcname = zend_u_str_case_fold(Z_TYPE(name->u.constant), Z_UNIVAL(name->u.constant), Z_UNILEN(name->u.constant), 0, &lcname_len);
        if (((lcname_len == sizeof("self")-1) &&
@@ -4988,6 +5008,8 @@ void zend_do_import(znode *ns_name, znode *new_name TSRMLS_DC) /* {{{ */
        if (new_name) {
                name = &new_name->u.constant;
        } else {
+               /* The form "import A::B" is eqivalent to "import A::B as B".
+                  So we extract the last part of compound name ti use as a new_name */
                name = &tmp;
                if (UG(unicode)) {
                        UChar *p = u_memrchr(Z_USTRVAL_P(ns), ':', Z_USTRLEN_P(ns));
@@ -4997,7 +5019,7 @@ void zend_do_import(znode *ns_name, znode *new_name TSRMLS_DC) /* {{{ */
                                *name = *ns;
                                zval_copy_ctor(name);
                                warn = 1;
-                       }                       
+                       }
                } else {
                        char *p = zend_memrchr(Z_STRVAL_P(ns), ':', Z_STRLEN_P(ns));
                        if (p) {
@@ -5006,7 +5028,7 @@ void zend_do_import(znode *ns_name, znode *new_name TSRMLS_DC) /* {{{ */
                                *name = *ns;
                                zval_copy_ctor(name);
                                warn = 1;
-                       }                       
+                       }
                }
        }
 
@@ -5018,7 +5040,7 @@ void zend_do_import(znode *ns_name, znode *new_name TSRMLS_DC) /* {{{ */
           ZEND_U_EQUAL(Z_TYPE_P(name), lcname, lcname_len, "parent", sizeof("parent")-1))) {
                zend_error(E_COMPILE_ERROR, "Cannot use '%R' as import name", Z_TYPE_P(name), Z_UNIVAL_P(name));
        }
-       
+
        if (zend_u_hash_exists(CG(class_table), Z_TYPE_P(name), lcname, lcname_len+1)) {
                zend_error(E_COMPILE_ERROR, "Import name '%R' coflicts with defined class", Z_TYPE_P(name), Z_UNIVAL_P(name));
        }
index ee0d00f60658484ccd9ea8144c51381f6e5cdcfb..a87b8eeff27ed35406d7ddc74b56e3b03dce31c4 100644 (file)
@@ -414,7 +414,7 @@ void zend_do_receive_arg(zend_uchar op, znode *var, znode *offset, znode *initia
 int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace TSRMLS_DC);
 void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC);
 void zend_do_clone(znode *result, znode *expr TSRMLS_DC);
-void zend_do_begin_dynamic_function_call(znode *function_name TSRMLS_DC);
+void zend_do_begin_dynamic_function_call(znode *function_name, int prefix_len 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 TSRMLS_DC);
 void zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC);
index 2ee7cdae34cfb6cfffa05afd59c65a7cfc06b44f..98276f08a726969f78a90d377a3e99525e84dcb7 100644 (file)
@@ -1144,6 +1144,8 @@ ZEND_API int zend_u_lookup_class_ex(zend_uchar type, zstr name, int name_length,
                lc_name = name;
                lc_name_len = name_length;
        }
+
+       /* Ignore leading "::" */
        if (type == IS_UNICODE &&
            lc_name.u[0] == ':' &&
            lc_name.u[1] == ':') {
index d625817c18f9c586478ac5c5d2378d9e7c62bb6f..4c1e6f470adee318b54b541308c18982bb9ad948 100644 (file)
@@ -658,7 +658,7 @@ function_call:
        |       fully_qualified_class_name T_PAAMAYIM_NEKUDOTAYIM variable_without_objects '(' { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_class_member_function_call(&$1, &$3 TSRMLS_CC); }
                        function_call_parameter_list
                        ')' { zend_do_end_function_call(NULL, &$$, &$6, 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); }
+       |       variable_without_objects  '(' { zend_do_end_variable_parse(BP_VAR_R, 0 TSRMLS_CC); zend_do_begin_dynamic_function_call(&$1, 0 TSRMLS_CC); }
                        function_call_parameter_list ')'
                        { zend_do_end_function_call(&$1, &$$, &$4, 0, 1 TSRMLS_CC); zend_do_extended_fcall_end(TSRMLS_C);}
 ;