From: Zeev Suraski Date: Wed, 5 Mar 2003 13:25:33 +0000 (+0000) Subject: Implement $obj::static_func() X-Git-Tag: RELEASE_0_5~606 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6ad2420d2d5797545e288a937f5eb35f4f46a5cf;p=php Implement $obj::static_func() --- diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 1840f6fbbb..5dc8e1a87f 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1208,29 +1208,33 @@ void do_fetch_class(znode *result, znode *namespace_name, znode *class_name TSRM SET_UNUSED(opline->op1); } CG(catch_begin) = fetch_class_op_number; - if(class_name) { - zend_str_tolower(class_name->u.constant.value.str.val, class_name->u.constant.value.str.len); - } - if(class_name == NULL) { - SET_UNUSED(opline->op2); - opline->extended_value = ZEND_FETCH_CLASS_MAIN; - } else if ((class_name->u.constant.value.str.len == (sizeof("self") - 1)) && - !memcmp(class_name->u.constant.value.str.val, "self", sizeof("self"))) { - SET_UNUSED(opline->op2); - opline->extended_value = ZEND_FETCH_CLASS_SELF; - zval_dtor(&class_name->u.constant); - } else if ((class_name->u.constant.value.str.len == (sizeof("parent") - 1)) && - !memcmp(class_name->u.constant.value.str.val, "parent", sizeof("parent"))) { - SET_UNUSED(opline->op2); - opline->extended_value = ZEND_FETCH_CLASS_PARENT; - zval_dtor(&class_name->u.constant); - } else if ((class_name->u.constant.value.str.len == (sizeof("main") - 1)) && - !memcmp(class_name->u.constant.value.str.val, "main", sizeof("main"))) { + if (class_name) { + if (class_name->op_type == IS_CONST) { + zend_str_tolower(class_name->u.constant.value.str.val, class_name->u.constant.value.str.len); + if ((class_name->u.constant.value.str.len == (sizeof("self") - 1)) && + !memcmp(class_name->u.constant.value.str.val, "self", sizeof("self"))) { + SET_UNUSED(opline->op2); + opline->extended_value = ZEND_FETCH_CLASS_SELF; + zval_dtor(&class_name->u.constant); + } else if ((class_name->u.constant.value.str.len == (sizeof("parent") - 1)) && + !memcmp(class_name->u.constant.value.str.val, "parent", sizeof("parent"))) { + SET_UNUSED(opline->op2); + opline->extended_value = ZEND_FETCH_CLASS_PARENT; + zval_dtor(&class_name->u.constant); + } else if ((class_name->u.constant.value.str.len == (sizeof("main") - 1)) && + !memcmp(class_name->u.constant.value.str.val, "main", sizeof("main"))) { + SET_UNUSED(opline->op2); + opline->extended_value = ZEND_FETCH_CLASS_MAIN; + zval_dtor(&class_name->u.constant); + } else { + opline->op2 = *class_name; + } + } else { + opline->op2 = *class_name; + } + } else { SET_UNUSED(opline->op2); opline->extended_value = ZEND_FETCH_CLASS_MAIN; - zval_dtor(&class_name->u.constant); - } else { - opline->op2 = *class_name; } opline->result.u.var = get_temporary_variable(CG(active_op_array)); opline->result.op_type = IS_CONST; /* FIXME: Hack so that INIT_FCALL_BY_NAME still knows this is a class */ diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 39a7b01b3d..412e04380b 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2303,6 +2303,7 @@ int zend_import_const_handler(ZEND_OPCODE_HANDLER_ARGS) int zend_fetch_class_handler(ZEND_OPCODE_HANDLER_ARGS) { zend_class_entry **pce; + zend_class_entry *ce = NULL; zend_bool is_const; char *class_name_strval; zend_uint class_name_strlen; @@ -2335,48 +2336,59 @@ int zend_fetch_class_handler(ZEND_OPCODE_HANDLER_ARGS) is_const = (EX(opline)->op2.op_type == IS_CONST); if (is_const) { - class_name_strval = EX(opline)->op2.u.constant.value.str.val; - class_name_strlen = EX(opline)->op2.u.constant.value.str.len; +{ + class_name_strval = EX(opline)->op2.u.constant.value.str.val; + class_name_strlen = EX(opline)->op2.u.constant.value.str.len; + } } else { class_name = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R); - tmp = *class_name; - zval_copy_ctor(&tmp); - convert_to_string(&tmp); - zend_str_tolower(tmp.value.str.val, tmp.value.str.len); + if (class_name->type == IS_OBJECT) { + ce = Z_OBJCE_P(class_name); + } else { + tmp = *class_name; + zval_copy_ctor(&tmp); + convert_to_string(&tmp); + zend_str_tolower(tmp.value.str.val, tmp.value.str.len); - class_name_strval = tmp.value.str.val; - class_name_strlen = tmp.value.str.len; + class_name_strval = tmp.value.str.val; + class_name_strlen = tmp.value.str.len; + } } - if (EX(opline)->op1.op_type == IS_UNUSED && EX(opline)->extended_value != ZEND_FETCH_CLASS_GLOBAL) { - 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 && (*pce)->type == ZEND_NAMESPACE) { - retval = SUCCESS; + if (!ce) { + if (EX(opline)->op1.op_type == IS_UNUSED && EX(opline)->extended_value != ZEND_FETCH_CLASS_GLOBAL) { + 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 && (*pce)->type == ZEND_NAMESPACE) { + 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 || (*pce)->type != ZEND_NAMESPACE) { - zend_error(E_ERROR, "Namespace '%s' not found", EX(opline)->op1.u.constant.value.str.val); + 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 || (*pce)->type != ZEND_NAMESPACE) { + zend_error(E_ERROR, "Namespace '%s' not found", EX(opline)->op1.u.constant.value.str.val); + } + ns = *pce; } - ns = *pce; + retval = zend_hash_find(&ns->class_table, class_name_strval, class_name_strlen+1, (void **)&pce); + } + if (retval==SUCCESS) { + ce = *pce; } - retval = zend_hash_find(&ns->class_table, class_name_strval, class_name_strlen+1, (void **)&pce); } if (retval == FAILURE) { zend_error(E_ERROR, "Class '%s' not found", class_name_strval); } else { - EX_T(EX(opline)->result.u.var).EA.class_entry = *pce; + EX_T(EX(opline)->result.u.var).EA.class_entry = ce; } if (!is_const) { zval_dtor(&tmp); @@ -3120,7 +3132,7 @@ int zend_new_handler(ZEND_OPCODE_HANDLER_ARGS) } else { class_type = "abstract_class"; } - zend_error(E_ERROR, "Cannot instantiate %s %s", class_type, EX_T(EX(opline)->op1.u.var).EA.class_entry->name); + zend_error(E_ERROR, "Cannot instantiate %s %s", class_type, EX_T(EX(opline)->op1.u.var).EA.class_entry->name); } EX_T(EX(opline)->result.u.var).var.ptr_ptr = &EX_T(EX(opline)->result.u.var).var.ptr; ALLOC_ZVAL(EX_T(EX(opline)->result.u.var).var.ptr); diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index 31506e11db..50d495fbd6 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -643,7 +643,7 @@ function_call: parse_class_entry: T_NAMESPACE_NAME T_PAAMAYIM_NEKUDOTAYIM T_STRING T_PAAMAYIM_NEKUDOTAYIM { do_fetch_class(&$$, &$1, &$3 TSRMLS_CC); } - | T_STRING T_PAAMAYIM_NEKUDOTAYIM { do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); } + | static_or_variable_string T_PAAMAYIM_NEKUDOTAYIM { do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); } | T_PAAMAYIM_NEKUDOTAYIM { do_fetch_class(&$$, NULL, NULL TSRMLS_CC); } ;