Skip to content

Commit 046bdea

Browse files
author
Andi Gutmans
committed
- Support new classname::$class_name, e.g.:
<? class foo::bar { public $hello = "Hello, World\n"; } $name = "bar"; $obj = new foo::$name; print $obj->hello; ?>
1 parent 852ec13 commit 046bdea

File tree

2 files changed

+35
-35
lines changed

2 files changed

+35
-35
lines changed

Zend/zend_execute.c

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1798,14 +1798,14 @@ binary_assign_op_addr: {
17981798
case ZEND_FETCH_CLASS:
17991799
{
18001800
zend_class_entry **pce;
1801+
zend_bool is_const;
1802+
char *class_name_strval;
1803+
zend_uint class_name_strlen;
1804+
zval *class_name;
1805+
zval tmp;
1806+
int retval;
18011807

18021808
if (EX(opline)->op1.op_type == IS_UNUSED) {
1803-
zval tmp;
1804-
zval *class_name;
1805-
zend_bool is_const;
1806-
char *class_name_strval;
1807-
zend_uint class_name_strlen;
1808-
18091809
if (EX(opline)->extended_value == ZEND_FETCH_CLASS_SELF) {
18101810
if (!EG(scope)) {
18111811
zend_error(E_ERROR, "Cannot fetch self:: when no class scope is active");
@@ -1824,40 +1824,40 @@ binary_assign_op_addr: {
18241824
}
18251825
EX(Ts)[EX(opline)->result.u.var].EA.class_entry = EG(scope)->parent;
18261826
NEXT_OPCODE();
1827-
}
1827+
}
1828+
}
18281829

1829-
is_const = (EX(opline)->op2.op_type == IS_CONST);
1830+
is_const = (EX(opline)->op2.op_type == IS_CONST);
18301831

1831-
if (is_const) {
1832-
class_name_strval = EX(opline)->op2.u.constant.value.str.val;
1833-
class_name_strlen = EX(opline)->op2.u.constant.value.str.len;
1834-
} else {
1835-
class_name = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
1832+
if (is_const) {
1833+
class_name_strval = EX(opline)->op2.u.constant.value.str.val;
1834+
class_name_strlen = EX(opline)->op2.u.constant.value.str.len;
1835+
} else {
1836+
class_name = get_zval_ptr(&EX(opline)->op2, EX(Ts), &EG(free_op2), BP_VAR_R);
18361837

1837-
tmp = *class_name;
1838-
zval_copy_ctor(&tmp);
1839-
convert_to_string(&tmp);
1840-
zend_str_tolower(tmp.value.str.val, tmp.value.str.len);
1838+
tmp = *class_name;
1839+
zval_copy_ctor(&tmp);
1840+
convert_to_string(&tmp);
1841+
zend_str_tolower(tmp.value.str.val, tmp.value.str.len);
18411842

1842-
class_name_strval = tmp.value.str.val;
1843-
class_name_strlen = tmp.value.str.len;
1844-
}
1843+
class_name_strval = tmp.value.str.val;
1844+
class_name_strlen = tmp.value.str.len;
1845+
}
18451846

1846-
if (zend_lookup_class(class_name_strval, class_name_strlen, &pce TSRMLS_CC) == FAILURE) {
1847-
zend_error(E_ERROR, "Class '%s' not found", class_name_strval);
1848-
} else {
1849-
EX(Ts)[EX(opline)->result.u.var].EA.class_entry = *pce;
1850-
}
1851-
if (!is_const) {
1852-
zval_dtor(&tmp);
1853-
FREE_OP(EX(Ts), &EX(opline)->op2, EG(free_op2));
1854-
}
1847+
if (EX(opline)->op1.op_type == IS_UNUSED) {
1848+
retval = zend_lookup_class(class_name_strval, class_name_strlen, &pce TSRMLS_CC);
18551849
} else {
1856-
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) {
1857-
zend_error(E_ERROR, "Class '%s' not found", EX(opline)->op2.u.constant.value.str.val);
1858-
} else {
1859-
EX(Ts)[EX(opline)->result.u.var].EA.class_entry = *pce;
1860-
}
1850+
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);
1851+
}
1852+
1853+
if (retval == FAILURE) {
1854+
zend_error(E_ERROR, "Class '%s' not found", class_name_strval);
1855+
} else {
1856+
EX(Ts)[EX(opline)->result.u.var].EA.class_entry = *pce;
1857+
}
1858+
if (!is_const) {
1859+
zval_dtor(&tmp);
1860+
FREE_OP(EX(Ts), &EX(opline)->op2, EG(free_op2));
18611861
}
18621862
NEXT_OPCODE();
18631863
}

Zend/zend_language_parser.y

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ catch_or_import_class_entry:
586586
;
587587

588588
new_class_entry:
589-
parse_class_entry T_STRING { do_fetch_class(&$$, &$1, &$2 TSRMLS_CC); }
589+
parse_class_entry static_or_variable_string { do_fetch_class(&$$, &$1, &$2 TSRMLS_CC); }
590590
| static_or_variable_string { do_fetch_class(&$$, NULL, &$1 TSRMLS_CC); }
591591
;
592592

0 commit comments

Comments
 (0)