mirror of
https://github.com/php/php-src.git
synced 2026-04-02 21:52:36 +02:00
Reuse part of the class binding logic
This part of DECLARE_CLASS and DECLARE_CLASS_DELAYED is the same.
This commit is contained in:
@@ -1100,6 +1100,32 @@ ZEND_API zend_result do_bind_function(zend_function *func, zval *lcname) /* {{{
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API zend_class_entry *zend_bind_class_in_slot(
|
||||
zval *class_table_slot, zval *lcname, zend_string *lc_parent_name)
|
||||
{
|
||||
zend_class_entry *ce = Z_PTR_P(class_table_slot);
|
||||
zval *zv = zend_hash_set_bucket_key(
|
||||
EG(class_table), (Bucket *) class_table_slot, Z_STR_P(lcname));
|
||||
if (UNEXPECTED(!zv)) {
|
||||
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));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ce->ce_flags & ZEND_ACC_LINKED) {
|
||||
return ce;
|
||||
}
|
||||
|
||||
ce = zend_do_link_class(ce, lc_parent_name, Z_STR_P(lcname));
|
||||
if (ce) {
|
||||
return ce;
|
||||
}
|
||||
|
||||
/* Reload bucket pointer, the hash table may have been reallocated */
|
||||
zv = zend_hash_find(EG(class_table), Z_STR_P(lcname));
|
||||
zend_hash_set_bucket_key(EG(class_table), (Bucket *) zv, Z_STR_P(lcname + 1));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZEND_API zend_result do_bind_class(zval *lcname, zend_string *lc_parent_name) /* {{{ */
|
||||
{
|
||||
zend_class_entry *ce;
|
||||
@@ -1131,26 +1157,7 @@ ZEND_API zend_result do_bind_class(zval *lcname, zend_string *lc_parent_name) /*
|
||||
}
|
||||
|
||||
/* Register the derived class */
|
||||
ce = (zend_class_entry*)Z_PTR_P(zv);
|
||||
zv = zend_hash_set_bucket_key(EG(class_table), (Bucket*)zv, Z_STR_P(lcname));
|
||||
if (UNEXPECTED(!zv)) {
|
||||
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));
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (ce->ce_flags & ZEND_ACC_LINKED) {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
ce = zend_do_link_class(ce, lc_parent_name, Z_STR_P(lcname));
|
||||
if (!ce) {
|
||||
/* Reload bucket pointer, the hash table may have been reallocated */
|
||||
zv = zend_hash_find(EG(class_table), Z_STR_P(lcname));
|
||||
zend_hash_set_bucket_key(EG(class_table), (Bucket *) zv, Z_STR_P(rtd_key));
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
return zend_bind_class_in_slot(zv, lcname, lc_parent_name) ? SUCCESS : FAILURE;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
||||
@@ -797,6 +797,8 @@ bool zend_handle_encoding_declaration(zend_ast *ast);
|
||||
/* parser-driven code generators */
|
||||
void zend_do_free(znode *op1);
|
||||
|
||||
ZEND_API zend_class_entry *zend_bind_class_in_slot(
|
||||
zval *class_table_slot, zval *lcname, zend_string *lc_parent_name);
|
||||
ZEND_API zend_result do_bind_function(zend_function *func, zval *lcname);
|
||||
ZEND_API zend_result do_bind_class(zval *lcname, zend_string *lc_parent_name);
|
||||
ZEND_API uint32_t zend_build_delayed_early_binding_list(const zend_op_array *op_array);
|
||||
|
||||
@@ -7582,27 +7582,16 @@ ZEND_VM_HANDLER(144, ZEND_DECLARE_CLASS, CONST, ANY)
|
||||
ZEND_VM_HANDLER(145, ZEND_DECLARE_CLASS_DELAYED, CONST, CONST)
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *lcname, *zv;
|
||||
zend_class_entry *ce;
|
||||
|
||||
ce = CACHED_PTR(opline->extended_value);
|
||||
zend_class_entry *ce = CACHED_PTR(opline->extended_value);
|
||||
if (ce == NULL) {
|
||||
lcname = RT_CONSTANT(opline, opline->op1);
|
||||
zv = zend_hash_find_known_hash(EG(class_table), Z_STR_P(lcname + 1));
|
||||
zval *lcname = RT_CONSTANT(opline, opline->op1);
|
||||
zval *zv = zend_hash_find_known_hash(EG(class_table), Z_STR_P(lcname + 1));
|
||||
if (zv) {
|
||||
SAVE_OPLINE();
|
||||
ce = Z_CE_P(zv);
|
||||
zv = zend_hash_set_bucket_key(EG(class_table), (Bucket*)zv, Z_STR_P(lcname));
|
||||
if (UNEXPECTED(!zv)) {
|
||||
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));
|
||||
} else {
|
||||
ce = zend_do_link_class(ce, Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(lcname));
|
||||
if (!ce) {
|
||||
/* Reload bucket pointer, the hash table may have been reallocated */
|
||||
zv = zend_hash_find(EG(class_table), Z_STR_P(lcname));
|
||||
zend_hash_set_bucket_key(EG(class_table), (Bucket *) zv, Z_STR_P(lcname + 1));
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
ce = zend_bind_class_in_slot(zv, lcname, Z_STR_P(RT_CONSTANT(opline, opline->op2)));
|
||||
if (!ce) {
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
}
|
||||
CACHE_PTR(opline->extended_value, ce);
|
||||
|
||||
@@ -7355,27 +7355,16 @@ array_key_exists_array:
|
||||
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CLASS_DELAYED_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *lcname, *zv;
|
||||
zend_class_entry *ce;
|
||||
|
||||
ce = CACHED_PTR(opline->extended_value);
|
||||
zend_class_entry *ce = CACHED_PTR(opline->extended_value);
|
||||
if (ce == NULL) {
|
||||
lcname = RT_CONSTANT(opline, opline->op1);
|
||||
zv = zend_hash_find_known_hash(EG(class_table), Z_STR_P(lcname + 1));
|
||||
zval *lcname = RT_CONSTANT(opline, opline->op1);
|
||||
zval *zv = zend_hash_find_known_hash(EG(class_table), Z_STR_P(lcname + 1));
|
||||
if (zv) {
|
||||
SAVE_OPLINE();
|
||||
ce = Z_CE_P(zv);
|
||||
zv = zend_hash_set_bucket_key(EG(class_table), (Bucket*)zv, Z_STR_P(lcname));
|
||||
if (UNEXPECTED(!zv)) {
|
||||
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));
|
||||
} else {
|
||||
ce = zend_do_link_class(ce, Z_STR_P(RT_CONSTANT(opline, opline->op2)), Z_STR_P(lcname));
|
||||
if (!ce) {
|
||||
/* Reload bucket pointer, the hash table may have been reallocated */
|
||||
zv = zend_hash_find(EG(class_table), Z_STR_P(lcname));
|
||||
zend_hash_set_bucket_key(EG(class_table), (Bucket *) zv, Z_STR_P(lcname + 1));
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
ce = zend_bind_class_in_slot(zv, lcname, Z_STR_P(RT_CONSTANT(opline, opline->op2)));
|
||||
if (!ce) {
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
}
|
||||
CACHE_PTR(opline->extended_value, ce);
|
||||
|
||||
Reference in New Issue
Block a user