Skip to content

Commit ac99d5b

Browse files
committed
Simplify registration of unresolved classes
If we have an UNRESOLVED result, simply register all classes that occur in either of the types. I believe that's equivalent to what we're currently doing in a more complicated way.
1 parent 0c89eda commit ac99d5b

File tree

1 file changed

+26
-29
lines changed

1 file changed

+26
-29
lines changed

Zend/zend_inheritance.c

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ static zend_always_inline void register_unresolved_class(zend_string *name) {
225225
zend_hash_add_empty_element(CG(delayed_autoloads), name);
226226
}
227227

228-
static zend_class_entry *lookup_class(
228+
static zend_class_entry *lookup_class_ex(
229229
zend_class_entry *scope, zend_string *name, bool register_unresolved) {
230230
zend_class_entry *ce;
231231

@@ -270,6 +270,10 @@ static zend_class_entry *lookup_class(
270270
return NULL;
271271
}
272272

273+
static zend_class_entry *lookup_class(zend_class_entry *scope, zend_string *name) {
274+
return lookup_class_ex(scope, name, /* register_unresolved */ false);
275+
}
276+
273277
/* Instanceof that's safe to use on unlinked classes. */
274278
static bool unlinked_instanceof(zend_class_entry *ce1, zend_class_entry *ce2) {
275279
if (ce1 == ce2) {
@@ -350,7 +354,7 @@ static bool zend_type_permits_self(
350354
ZEND_TYPE_FOREACH(type, single_type) {
351355
if (ZEND_TYPE_HAS_NAME(*single_type)) {
352356
zend_string *name = resolve_class_name(scope, ZEND_TYPE_NAME(*single_type));
353-
zend_class_entry *ce = lookup_class(self, name, /* register_unresolved */ 0);
357+
zend_class_entry *ce = lookup_class(self, name);
354358
if (ce && unlinked_instanceof(self, ce)) {
355359
return 1;
356360
}
@@ -401,14 +405,13 @@ static void track_class_dependency(zend_class_entry *ce, zend_string *class_name
401405

402406
static inheritance_status zend_perform_covariant_class_type_check(
403407
zend_class_entry *fe_scope, zend_string *fe_class_name, zend_class_entry *fe_ce,
404-
zend_class_entry *proto_scope, zend_type proto_type,
405-
bool register_unresolved) {
408+
zend_class_entry *proto_scope, zend_type proto_type) {
406409
bool have_unresolved = 0;
407410
if (ZEND_TYPE_FULL_MASK(proto_type) & MAY_BE_OBJECT) {
408411
/* Currently, any class name would be allowed here. We still perform a class lookup
409412
* for forward-compatibility reasons, as we may have named types in the future that
410413
* are not classes (such as enums or typedefs). */
411-
if (!fe_ce) fe_ce = lookup_class(fe_scope, fe_class_name, register_unresolved);
414+
if (!fe_ce) fe_ce = lookup_class(fe_scope, fe_class_name);
412415
if (!fe_ce) {
413416
have_unresolved = 1;
414417
} else {
@@ -417,7 +420,7 @@ static inheritance_status zend_perform_covariant_class_type_check(
417420
}
418421
}
419422
if (ZEND_TYPE_FULL_MASK(proto_type) & MAY_BE_ITERABLE) {
420-
if (!fe_ce) fe_ce = lookup_class(fe_scope, fe_class_name, register_unresolved);
423+
if (!fe_ce) fe_ce = lookup_class(fe_scope, fe_class_name);
421424
if (!fe_ce) {
422425
have_unresolved = 1;
423426
} else if (unlinked_instanceof(fe_ce, zend_ce_traversable)) {
@@ -437,11 +440,10 @@ static inheritance_status zend_perform_covariant_class_type_check(
437440
return INHERITANCE_SUCCESS;
438441
}
439442

440-
if (!fe_ce) fe_ce = lookup_class(fe_scope, fe_class_name, register_unresolved);
441-
proto_ce =
442-
lookup_class(proto_scope, proto_class_name, register_unresolved);
443+
if (!fe_ce) fe_ce = lookup_class(fe_scope, fe_class_name);
444+
proto_ce = lookup_class(proto_scope, proto_class_name);
443445
} else if (ZEND_TYPE_HAS_CE(*single_type)) {
444-
if (!fe_ce) fe_ce = lookup_class(fe_scope, fe_class_name, register_unresolved);
446+
if (!fe_ce) fe_ce = lookup_class(fe_scope, fe_class_name);
445447
proto_ce = ZEND_TYPE_CE(*single_type);
446448
} else {
447449
continue;
@@ -459,6 +461,16 @@ static inheritance_status zend_perform_covariant_class_type_check(
459461
return have_unresolved ? INHERITANCE_UNRESOLVED : INHERITANCE_ERROR;
460462
}
461463

464+
static void register_unresolved_classes(zend_class_entry *scope, zend_type type) {
465+
zend_type *single_type;
466+
ZEND_TYPE_FOREACH(type, single_type) {
467+
if (ZEND_TYPE_HAS_NAME(*single_type)) {
468+
zend_string *class_name = resolve_class_name(scope, ZEND_TYPE_NAME(*single_type));
469+
lookup_class_ex(scope, class_name, /* register_unresolved */ true);
470+
}
471+
} ZEND_TYPE_FOREACH_END();
472+
}
473+
462474
static inheritance_status zend_perform_covariant_type_check(
463475
zend_class_entry *fe_scope, zend_type fe_type,
464476
zend_class_entry *proto_scope, zend_type proto_type)
@@ -516,13 +528,11 @@ static inheritance_status zend_perform_covariant_type_check(
516528
zend_string *fe_class_name =
517529
resolve_class_name(fe_scope, ZEND_TYPE_NAME(*single_type));
518530
status = zend_perform_covariant_class_type_check(
519-
fe_scope, fe_class_name, NULL,
520-
proto_scope, proto_type, /* register_unresolved */ 0);
531+
fe_scope, fe_class_name, NULL, proto_scope, proto_type);
521532
} else if (ZEND_TYPE_HAS_CE(*single_type)) {
522533
zend_class_entry *fe_ce = ZEND_TYPE_CE(*single_type);
523534
status = zend_perform_covariant_class_type_check(
524-
fe_scope, fe_ce->name, fe_ce,
525-
proto_scope, proto_type, /* register_unresolved */ 0);
535+
fe_scope, fe_ce->name, fe_ce, proto_scope, proto_type);
526536
} else {
527537
continue;
528538
}
@@ -540,21 +550,8 @@ static inheritance_status zend_perform_covariant_type_check(
540550
return INHERITANCE_SUCCESS;
541551
}
542552

543-
/* Register all classes that may have to be resolved */
544-
ZEND_TYPE_FOREACH(fe_type, single_type) {
545-
if (ZEND_TYPE_HAS_NAME(*single_type)) {
546-
zend_string *fe_class_name =
547-
resolve_class_name(fe_scope, ZEND_TYPE_NAME(*single_type));
548-
zend_perform_covariant_class_type_check(
549-
fe_scope, fe_class_name, NULL,
550-
proto_scope, proto_type, /* register_unresolved */ 1);
551-
} else if (ZEND_TYPE_HAS_CE(*single_type)) {
552-
zend_class_entry *fe_ce = ZEND_TYPE_CE(*single_type);
553-
zend_perform_covariant_class_type_check(
554-
fe_scope, fe_ce->name, fe_ce,
555-
proto_scope, proto_type, /* register_unresolved */ 1);
556-
}
557-
} ZEND_TYPE_FOREACH_END();
553+
register_unresolved_classes(fe_scope, fe_type);
554+
register_unresolved_classes(proto_scope, proto_type);
558555
return INHERITANCE_UNRESOLVED;
559556
}
560557

0 commit comments

Comments
 (0)