Implement $obj::static_func()

This commit is contained in:
Zeev Suraski 2003-03-05 13:25:33 +00:00
parent 5ab857c8b9
commit 6ad2420d2d
3 changed files with 66 additions and 50 deletions

View File

@ -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"))) {
SET_UNUSED(opline->op2);
opline->extended_value = ZEND_FETCH_CLASS_MAIN;
zval_dtor(&class_name->u.constant);
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 {
opline->op2 = *class_name;
SET_UNUSED(opline->op2);
opline->extended_value = ZEND_FETCH_CLASS_MAIN;
}
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 */

View File

@ -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 (!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;
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);

View File

@ -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); }
;