Skip to content

Commit dcf5e5b

Browse files
committed
Reuse part of the class binding logic
This part of DECLARE_CLASS and DECLARE_CLASS_DELAYED is the same.
1 parent 8834cf0 commit dcf5e5b

File tree

4 files changed

+41
-54
lines changed

4 files changed

+41
-54
lines changed

Zend/zend_compile.c

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,32 @@ ZEND_API zend_result do_bind_function(zend_function *func, zval *lcname) /* {{{
11001100
}
11011101
/* }}} */
11021102

1103+
ZEND_API zend_class_entry *zend_bind_class_in_slot(
1104+
zval *class_table_slot, zval *lcname, zend_string *lc_parent_name)
1105+
{
1106+
zend_class_entry *ce = Z_PTR_P(class_table_slot);
1107+
zval *zv = zend_hash_set_bucket_key(
1108+
EG(class_table), (Bucket *) class_table_slot, Z_STR_P(lcname));
1109+
if (UNEXPECTED(!zv)) {
1110+
zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(ce), ZSTR_VAL(ce->name));
1111+
return NULL;
1112+
}
1113+
1114+
if (ce->ce_flags & ZEND_ACC_LINKED) {
1115+
return ce;
1116+
}
1117+
1118+
ce = zend_do_link_class(ce, lc_parent_name, Z_STR_P(lcname));
1119+
if (ce) {
1120+
return ce;
1121+
}
1122+
1123+
/* Reload bucket pointer, the hash table may have been reallocated */
1124+
zv = zend_hash_find(EG(class_table), Z_STR_P(lcname));
1125+
zend_hash_set_bucket_key(EG(class_table), (Bucket *) zv, Z_STR_P(lcname + 1));
1126+
return NULL;
1127+
}
1128+
11031129
ZEND_API zend_result do_bind_class(zval *lcname, zend_string *lc_parent_name) /* {{{ */
11041130
{
11051131
zend_class_entry *ce;
@@ -1131,26 +1157,7 @@ ZEND_API zend_result do_bind_class(zval *lcname, zend_string *lc_parent_name) /*
11311157
}
11321158

11331159
/* Register the derived class */
1134-
ce = (zend_class_entry*)Z_PTR_P(zv);
1135-
zv = zend_hash_set_bucket_key(EG(class_table), (Bucket*)zv, Z_STR_P(lcname));
1136-
if (UNEXPECTED(!zv)) {
1137-
zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(ce), ZSTR_VAL(ce->name));
1138-
return FAILURE;
1139-
}
1140-
1141-
if (ce->ce_flags & ZEND_ACC_LINKED) {
1142-
return SUCCESS;
1143-
}
1144-
1145-
ce = zend_do_link_class(ce, lc_parent_name, Z_STR_P(lcname));
1146-
if (!ce) {
1147-
/* Reload bucket pointer, the hash table may have been reallocated */
1148-
zv = zend_hash_find(EG(class_table), Z_STR_P(lcname));
1149-
zend_hash_set_bucket_key(EG(class_table), (Bucket *) zv, Z_STR_P(rtd_key));
1150-
return FAILURE;
1151-
}
1152-
1153-
return SUCCESS;
1160+
return zend_bind_class_in_slot(zv, lcname, lc_parent_name) ? SUCCESS : FAILURE;
11541161
}
11551162
/* }}} */
11561163

Zend/zend_compile.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,8 @@ bool zend_handle_encoding_declaration(zend_ast *ast);
797797
/* parser-driven code generators */
798798
void zend_do_free(znode *op1);
799799

800+
ZEND_API zend_class_entry *zend_bind_class_in_slot(
801+
zval *class_table_slot, zval *lcname, zend_string *lc_parent_name);
800802
ZEND_API zend_result do_bind_function(zend_function *func, zval *lcname);
801803
ZEND_API zend_result do_bind_class(zval *lcname, zend_string *lc_parent_name);
802804
ZEND_API uint32_t zend_build_delayed_early_binding_list(const zend_op_array *op_array);

Zend/zend_vm_def.h

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7582,27 +7582,16 @@ ZEND_VM_HANDLER(144, ZEND_DECLARE_CLASS, CONST, ANY)
75827582
ZEND_VM_HANDLER(145, ZEND_DECLARE_CLASS_DELAYED, CONST, CONST)
75837583
{
75847584
USE_OPLINE
7585-
zval *lcname, *zv;
7586-
zend_class_entry *ce;
75877585

7588-
ce = CACHED_PTR(opline->extended_value);
7586+
zend_class_entry *ce = CACHED_PTR(opline->extended_value);
75897587
if (ce == NULL) {
7590-
lcname = RT_CONSTANT(opline, opline->op1);
7591-
zv = zend_hash_find_known_hash(EG(class_table), Z_STR_P(lcname + 1));
7588+
zval *lcname = RT_CONSTANT(opline, opline->op1);
7589+
zval *zv = zend_hash_find_known_hash(EG(class_table), Z_STR_P(lcname + 1));
75927590
if (zv) {
75937591
SAVE_OPLINE();
7594-
ce = Z_CE_P(zv);
7595-
zv = zend_hash_set_bucket_key(EG(class_table), (Bucket*)zv, Z_STR_P(lcname));
7596-
if (UNEXPECTED(!zv)) {
7597-
zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(ce), ZSTR_VAL(ce->name));
7598-
} else {
7599-
ce = zend_do_link_class(ce, Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(lcname));
7600-
if (!ce) {
7601-
/* Reload bucket pointer, the hash table may have been reallocated */
7602-
zv = zend_hash_find(EG(class_table), Z_STR_P(lcname));
7603-
zend_hash_set_bucket_key(EG(class_table), (Bucket *) zv, Z_STR_P(lcname + 1));
7604-
HANDLE_EXCEPTION();
7605-
}
7592+
ce = zend_bind_class_in_slot(zv, lcname, Z_STR_P(RT_CONSTANT(opline, opline->op2)));
7593+
if (!ce) {
7594+
HANDLE_EXCEPTION();
76067595
}
76077596
}
76087597
CACHE_PTR(opline->extended_value, ce);

Zend/zend_vm_execute.h

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7355,27 +7355,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ARRAY_KEY_EXISTS_SPEC_CONST_CO
73557355
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
73567356
{
73577357
USE_OPLINE
7358-
zval *lcname, *zv;
7359-
zend_class_entry *ce;
73607358

7361-
ce = CACHED_PTR(opline->extended_value);
7359+
zend_class_entry *ce = CACHED_PTR(opline->extended_value);
73627360
if (ce == NULL) {
7363-
lcname = RT_CONSTANT(opline, opline->op1);
7364-
zv = zend_hash_find_known_hash(EG(class_table), Z_STR_P(lcname + 1));
7361+
zval *lcname = RT_CONSTANT(opline, opline->op1);
7362+
zval *zv = zend_hash_find_known_hash(EG(class_table), Z_STR_P(lcname + 1));
73657363
if (zv) {
73667364
SAVE_OPLINE();
7367-
ce = Z_CE_P(zv);
7368-
zv = zend_hash_set_bucket_key(EG(class_table), (Bucket*)zv, Z_STR_P(lcname));
7369-
if (UNEXPECTED(!zv)) {
7370-
zend_error_noreturn(E_COMPILE_ERROR, "Cannot declare %s %s, because the name is already in use", zend_get_object_type(ce), ZSTR_VAL(ce->name));
7371-
} else {
7372-
ce = zend_do_link_class(ce, Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(lcname));
7373-
if (!ce) {
7374-
/* Reload bucket pointer, the hash table may have been reallocated */
7375-
zv = zend_hash_find(EG(class_table), Z_STR_P(lcname));
7376-
zend_hash_set_bucket_key(EG(class_table), (Bucket *) zv, Z_STR_P(lcname + 1));
7377-
HANDLE_EXCEPTION();
7378-
}
7365+
ce = zend_bind_class_in_slot(zv, lcname, Z_STR_P(RT_CONSTANT(opline, opline->op2)));
7366+
if (!ce) {
7367+
HANDLE_EXCEPTION();
73797368
}
73807369
}
73817370
CACHE_PTR(opline->extended_value, ce);

0 commit comments

Comments
 (0)