diff --git a/Zend/tests/autoloading/function/global_fallback002.phpt b/Zend/tests/autoloading/function/global_fallback002.phpt index 5af856c4c5319..df4d3d96a6aa4 100644 --- a/Zend/tests/autoloading/function/global_fallback002.phpt +++ b/Zend/tests/autoloading/function/global_fallback002.phpt @@ -1,18 +1,25 @@ --TEST-- -Fallback to global function should not trigger autoloading. +Fallback to global function triggers autoloading once. --FILE-- --EXPECT-- -string(5) "Hello" +function loader called with bar\foo +I am foo in global namespace. diff --git a/Zend/tests/autoloading/function/global_fallback003.phpt b/Zend/tests/autoloading/function/global_fallback003.phpt new file mode 100644 index 0000000000000..1d93dd8499fec --- /dev/null +++ b/Zend/tests/autoloading/function/global_fallback003.phpt @@ -0,0 +1,27 @@ +--TEST-- +Fallback to non-existent function triggers autoloading once in namespace, once in global. +--FILE-- +getMessage() . "\n"; + } +} + +?> +--EXPECT-- +function loader called with bar\non_existent_function +function loader called with non_existent_function +Error correctly caught: Call to undefined function bar\non_existent_function() diff --git a/Zend/tests/autoloading/function/global_fallback_doesnt_repeat_autoloading.phpt b/Zend/tests/autoloading/function/global_fallback_doesnt_repeat_autoloading.phpt new file mode 100644 index 0000000000000..5d7dd91da002a --- /dev/null +++ b/Zend/tests/autoloading/function/global_fallback_doesnt_repeat_autoloading.phpt @@ -0,0 +1,42 @@ +--TEST-- +Fallback to global function should trigger autoloading only once per namespace. +--FILE-- + +--EXPECT-- +function loader called with bar\foo +I am foo in global namespace. +I am foo in global namespace. +I am foo in global namespace. +I am foo in global namespace. +I am foo in global namespace. +function loader called with Quux\foo +I am foo in global namespace. diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index a5c5e4458ccce..d5d26fba92736 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -3859,19 +3859,22 @@ ZEND_VM_HOT_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT) if (UNEXPECTED(fbc == NULL)) { zval *function_name = (zval *)RT_CONSTANT(opline, opline->op2); /* Fetch lowercase name stored in the next literal slot */ - fbc = zend_lookup_function_ex(Z_STR_P(function_name), Z_STR_P(function_name+1), /* use_autoload */ false); + fbc = zend_lookup_function_ex(Z_STR_P(function_name), Z_STR_P(function_name+1), /* use_autoload */ true); if (UNEXPECTED(fbc == NULL)) { if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } /* Fallback onto global namespace, by fetching the unqualified lowercase name stored in the second literal slot */ - fbc = zend_lookup_function_ex(Z_STR_P(function_name+2), Z_STR_P(function_name+2), /* use_autoload */ false); + fbc = zend_lookup_function_ex(Z_STR_P(function_name+2), Z_STR_P(function_name+2), /* use_autoload */ true); if (fbc == NULL) { if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } ZEND_VM_DISPATCH_TO_HELPER(zend_undefined_function_helper); } + else { + do_bind_function(fbc, function_name); + } } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 0a753f5ad3cd1..93ac35674c59a 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3764,19 +3764,22 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_N if (UNEXPECTED(fbc == NULL)) { zval *function_name = (zval *)RT_CONSTANT(opline, opline->op2); /* Fetch lowercase name stored in the next literal slot */ - fbc = zend_lookup_function_ex(Z_STR_P(function_name), Z_STR_P(function_name+1), /* use_autoload */ false); + fbc = zend_lookup_function_ex(Z_STR_P(function_name), Z_STR_P(function_name+1), /* use_autoload */ true); if (UNEXPECTED(fbc == NULL)) { if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } /* Fallback onto global namespace, by fetching the unqualified lowercase name stored in the second literal slot */ - fbc = zend_lookup_function_ex(Z_STR_P(function_name+2), Z_STR_P(function_name+2), /* use_autoload */ false); + fbc = zend_lookup_function_ex(Z_STR_P(function_name+2), Z_STR_P(function_name+2), /* use_autoload */ true); if (fbc == NULL) { if (UNEXPECTED(EG(exception))) { HANDLE_EXCEPTION(); } ZEND_VM_TAIL_CALL(zend_undefined_function_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU)); } + else { + do_bind_function(fbc, function_name); + } } if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) { init_func_run_time_cache(&fbc->op_array);