Skip to content

Commit 034741f

Browse files
committed
Simplify spl_autoload_perform() implementation
And convert alfi.obj from zval to zend_object*.
1 parent c23edd2 commit 034741f

File tree

1 file changed

+26
-52
lines changed

1 file changed

+26
-52
lines changed

ext/spl/php_spl.c

Lines changed: 26 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -368,16 +368,16 @@ PHP_FUNCTION(spl_autoload_extensions)
368368

369369
typedef struct {
370370
zend_function *func_ptr;
371-
zval obj;
371+
zend_object *obj;
372372
zval closure;
373373
zend_class_entry *ce;
374374
} autoload_func_info;
375375

376376
static void autoload_func_info_dtor(zval *element)
377377
{
378378
autoload_func_info *alfi = (autoload_func_info*)Z_PTR_P(element);
379-
if (!Z_ISUNDEF(alfi->obj)) {
380-
zval_ptr_dtor(&alfi->obj);
379+
if (alfi->obj) {
380+
zend_object_release(alfi->obj);
381381
}
382382
if (alfi->func_ptr &&
383383
UNEXPECTED(alfi->func_ptr->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
@@ -395,51 +395,27 @@ static zend_class_entry *spl_perform_autoload(zend_string *class_name, zend_stri
395395
return NULL;
396396
}
397397

398-
HashPosition pos;
399-
zend_ulong num_idx;
400-
zend_function *func;
401-
zend_fcall_info fci;
402-
zend_fcall_info_cache fcic;
403-
zval params[1];
404-
zval retval;
405-
zend_string *func_name;
406-
407-
fci.size = sizeof(fci);
408-
fci.retval = &retval;
409-
fci.param_count = 1;
410-
fci.params = params;
411-
fci.no_separation = 1;
412-
ZVAL_STR(&params[0], class_name);
413-
414-
ZVAL_UNDEF(&fci.function_name); /* Unused */
415-
416398
/* We don't use ZEND_HASH_FOREACH here,
417399
* because autoloaders may be added/removed during autoloading. */
400+
HashPosition pos;
418401
zend_hash_internal_pointer_reset_ex(SPL_G(autoload_functions), &pos);
419-
while (zend_hash_get_current_key_ex(SPL_G(autoload_functions), &func_name, &num_idx, &pos) == HASH_KEY_IS_STRING) {
402+
while (1) {
420403
autoload_func_info *alfi =
421404
zend_hash_get_current_data_ptr_ex(SPL_G(autoload_functions), &pos);
422-
func = alfi->func_ptr;
405+
if (!alfi) {
406+
break;
407+
}
408+
409+
zend_function *func = alfi->func_ptr;
423410
if (UNEXPECTED(func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
424411
func = emalloc(sizeof(zend_op_array));
425412
memcpy(func, alfi->func_ptr, sizeof(zend_op_array));
426413
zend_string_addref(func->op_array.function_name);
427414
}
428-
ZVAL_UNDEF(&retval);
429-
fcic.function_handler = func;
430-
if (Z_ISUNDEF(alfi->obj)) {
431-
fci.object = NULL;
432-
fcic.object = NULL;
433-
fcic.called_scope = alfi->ce;
434-
} else {
435-
fci.object = Z_OBJ(alfi->obj);
436-
fcic.object = Z_OBJ(alfi->obj);
437-
fcic.called_scope = Z_OBJCE(alfi->obj);
438-
}
439-
440-
zend_call_function(&fci, &fcic);
441-
zval_ptr_dtor(&retval);
442415

416+
zval param;
417+
ZVAL_STR(&param, class_name);
418+
zend_call_known_function(func, alfi->obj, alfi->ce, NULL, 1, &param);
443419
if (EG(exception)) {
444420
break;
445421
}
@@ -487,7 +463,6 @@ PHP_FUNCTION(spl_autoload_register)
487463
zend_bool do_throw = 1;
488464
zend_bool prepend = 0;
489465
autoload_func_info alfi;
490-
zend_object *obj_ptr;
491466
zend_fcall_info fci = {0};
492467
zend_fcall_info_cache fcc;
493468

@@ -512,7 +487,7 @@ PHP_FUNCTION(spl_autoload_register)
512487
if (ZEND_FCI_INITIALIZED(fci)) {
513488
alfi.ce = fcc.calling_scope;
514489
alfi.func_ptr = fcc.function_handler;
515-
obj_ptr = fcc.object;
490+
alfi.obj = !(alfi.func_ptr->common.fn_flags & ZEND_ACC_STATIC) ? fcc.object : NULL;
516491

517492
if (fcc.function_handler->type == ZEND_INTERNAL_FUNCTION &&
518493
fcc.function_handler->internal_function.handler == zif_spl_autoload_call) {
@@ -547,15 +522,12 @@ PHP_FUNCTION(spl_autoload_register)
547522
goto skip;
548523
}
549524

550-
if (obj_ptr && !(alfi.func_ptr->common.fn_flags & ZEND_ACC_STATIC)) {
525+
if (alfi.obj) {
551526
/* add object id to the hash to ensure uniqueness, for more reference look at bug #40091 */
552527
lc_name = zend_string_extend(lc_name, ZSTR_LEN(lc_name) + sizeof(uint32_t), 0);
553-
memcpy(ZSTR_VAL(lc_name) + ZSTR_LEN(lc_name) - sizeof(uint32_t), &obj_ptr->handle, sizeof(uint32_t));
528+
memcpy(ZSTR_VAL(lc_name) + ZSTR_LEN(lc_name) - sizeof(uint32_t), &alfi.obj->handle, sizeof(uint32_t));
554529
ZSTR_VAL(lc_name)[ZSTR_LEN(lc_name)] = '\0';
555-
ZVAL_OBJ(&alfi.obj, obj_ptr);
556-
Z_ADDREF(alfi.obj);
557-
} else {
558-
ZVAL_UNDEF(&alfi.obj);
530+
GC_ADDREF(alfi.obj);
559531
}
560532

561533
if (UNEXPECTED(alfi.func_ptr == &EG(trampoline))) {
@@ -566,8 +538,8 @@ PHP_FUNCTION(spl_autoload_register)
566538
alfi.func_ptr = copy;
567539
}
568540
if (zend_hash_add_mem(SPL_G(autoload_functions), lc_name, &alfi, sizeof(autoload_func_info)) == NULL) {
569-
if (obj_ptr && !(alfi.func_ptr->common.fn_flags & ZEND_ACC_STATIC)) {
570-
Z_DELREF(alfi.obj);
541+
if (alfi.obj && !(alfi.func_ptr->common.fn_flags & ZEND_ACC_STATIC)) {
542+
GC_DELREF(alfi.obj);
571543
}
572544
if (!Z_ISUNDEF(alfi.closure)) {
573545
Z_DELREF(alfi.closure);
@@ -587,9 +559,9 @@ PHP_FUNCTION(spl_autoload_register)
587559
autoload_func_info spl_alfi;
588560
spl_alfi.func_ptr = zend_hash_str_find_ptr(
589561
CG(function_table), "spl_autoload", sizeof("spl_autoload") - 1);
590-
ZVAL_UNDEF(&spl_alfi.obj);
591-
ZVAL_UNDEF(&spl_alfi.closure);
562+
spl_alfi.obj = NULL;
592563
spl_alfi.ce = NULL;
564+
ZVAL_UNDEF(&spl_alfi.closure);
593565
zend_hash_add_mem(SPL_G(autoload_functions), spl_alfi.func_ptr->common.function_name,
594566
&spl_alfi, sizeof(autoload_func_info));
595567
if (prepend && SPL_G(autoload_functions)->nNumOfElements > 1) {
@@ -689,9 +661,11 @@ PHP_FUNCTION(spl_autoload_functions)
689661
zval tmp;
690662

691663
array_init(&tmp);
692-
if (!Z_ISUNDEF(alfi->obj)) {
693-
Z_ADDREF(alfi->obj);
694-
add_next_index_zval(&tmp, &alfi->obj);
664+
if (alfi->obj) {
665+
zval obj_zv;
666+
ZVAL_OBJ(&obj_zv, alfi->obj);
667+
Z_ADDREF(obj_zv);
668+
add_next_index_zval(&tmp, &obj_zv);
695669
} else {
696670
add_next_index_str(&tmp, zend_string_copy(alfi->ce->name));
697671
}

0 commit comments

Comments
 (0)