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 */
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;
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);
} 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);