Browse Source

- Support new classname::$class_name, e.g.:

<?

	class foo::bar {
		public $hello = "Hello, World\n";
	}

	$name = "bar";
	$obj = new foo::$name;
	print $obj->hello;
?>
migration/unlabaled-1.29.2
Andi Gutmans 24 years ago
parent
commit
046bdeaaab
  1. 68
      Zend/zend_execute.c
  2. 2
      Zend/zend_language_parser.y

68
Zend/zend_execute.c

@ -1798,14 +1798,14 @@ binary_assign_op_addr_obj:
case ZEND_FETCH_CLASS:
{
zend_class_entry **pce;
zend_bool is_const;
char *class_name_strval;
zend_uint class_name_strlen;
zval *class_name;
zval tmp;
int retval;
if (EX(opline)->op1.op_type == IS_UNUSED) {
zval tmp;
zval *class_name;
zend_bool is_const;
char *class_name_strval;
zend_uint class_name_strlen;
if (EX(opline)->extended_value == ZEND_FETCH_CLASS_SELF) {
if (!EG(scope)) {
zend_error(E_ERROR, "Cannot fetch self:: when no class scope is active");
@ -1824,40 +1824,40 @@ binary_assign_op_addr_obj:
}
EX(Ts)[EX(opline)->result.u.var].EA.class_entry = EG(scope)->parent;
NEXT_OPCODE();
}
}
}
is_const = (EX(opline)->op2.op_type == IS_CONST);
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;
} else {
class_name = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
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;
} 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);
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 (zend_lookup_class(class_name_strval, class_name_strlen, &pce TSRMLS_CC) == FAILURE) {
zend_error(E_ERROR, "Class '%s' not found", class_name_strval);
} else {
EX(Ts)[EX(opline)->result.u.var].EA.class_entry = *pce;
}
if (!is_const) {
zval_dtor(&tmp);
FREE_OP(EX(Ts), &EX(opline)->op2, EG(free_op2));
}
if (EX(opline)->op1.op_type == IS_UNUSED) {
retval = zend_lookup_class(class_name_strval, class_name_strlen, &pce TSRMLS_CC);
} else {
if (zend_hash_find(&EX(Ts)[EX(opline)->op1.u.var].EA.class_entry->class_table, EX(opline)->op2.u.constant.value.str.val, EX(opline)->op2.u.constant.value.str.len+1, (void **)&pce) == FAILURE) {
zend_error(E_ERROR, "Class '%s' not found", EX(opline)->op2.u.constant.value.str.val);
} else {
EX(Ts)[EX(opline)->result.u.var].EA.class_entry = *pce;
}
retval = zend_hash_find(&EX(Ts)[EX(opline)->op1.u.var].EA.class_entry->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(Ts)[EX(opline)->result.u.var].EA.class_entry = *pce;
}
if (!is_const) {
zval_dtor(&tmp);
FREE_OP(EX(Ts), &EX(opline)->op2, EG(free_op2));
}
NEXT_OPCODE();
}

2
Zend/zend_language_parser.y

@ -586,7 +586,7 @@ catch_or_import_class_entry:
;
new_class_entry:
parse_class_entry T_STRING { do_fetch_class(&$$, &$1, &$2 TSRMLS_CC); }
parse_class_entry static_or_variable_string { do_fetch_class(&$$, &$1, &$2 TSRMLS_CC); }
| static_or_variable_string { do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); }
;

Loading…
Cancel
Save