diff options
author | Dmitry Stogov <dmitry@zend.com> | 2020-03-12 16:31:24 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2020-03-12 16:31:24 +0300 |
commit | 2dddab01ae6a5427d9f6f38770cea4553e93b033 (patch) | |
tree | 5e04f2d91956e224b235fc84f232bceab7da10c4 /Zend | |
parent | ddc3f3d595c28b7b9756dc346c0895000cf2631f (diff) | |
download | php-git-2dddab01ae6a5427d9f6f38770cea4553e93b033.tar.gz |
Avoid "Anonymous class wasn't preloaded" error by lazely loading of not preloaded part of a preloaded script
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/zend.c | 1 | ||||
-rw-r--r-- | Zend/zend.h | 3 | ||||
-rw-r--r-- | Zend/zend_compile.c | 16 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 13 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 13 |
5 files changed, 39 insertions, 7 deletions
diff --git a/Zend/zend.c b/Zend/zend.c index 97ac3327ca..a9ae03e624 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -81,6 +81,7 @@ ZEND_API char *(*zend_getenv)(char *name, size_t name_len); ZEND_API zend_string *(*zend_resolve_path)(const char *filename, size_t filename_len); ZEND_API int (*zend_post_startup_cb)(void) = NULL; ZEND_API void (*zend_post_shutdown_cb)(void) = NULL; +ZEND_API int (*zend_preload_autoload)(zend_string *filename) = NULL; void (*zend_on_timeout)(int seconds); diff --git a/Zend/zend.h b/Zend/zend.h index 9aefc8d26a..94fd9a3559 100644 --- a/Zend/zend.h +++ b/Zend/zend.h @@ -292,6 +292,9 @@ extern ZEND_API zend_string *(*zend_resolve_path)(const char *filename, size_t f extern ZEND_API int (*zend_post_startup_cb)(void); extern ZEND_API void (*zend_post_shutdown_cb)(void); +/* Callback for loading of not preloaded part of the script */ +extern ZEND_API int (*zend_preload_autoload)(zend_string *filename); + ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); /* If filename is NULL the default filename is used. */ diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 5661f26439..970011ac08 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1072,11 +1072,21 @@ ZEND_API int do_bind_class(zval *lcname, zend_string *lc_parent_name) /* {{{ */ ce = zend_hash_find_ptr(EG(class_table), Z_STR_P(lcname)); if (ce) { 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; } else { - ZEND_ASSERT(EG(current_execute_data)->func->op_array.fn_flags & ZEND_ACC_PRELOADED); - zend_error_noreturn(E_ERROR, "Class %s wasn't preloaded", Z_STRVAL_P(lcname)); + do { + if (zend_preload_autoload + && zend_preload_autoload(EG(current_execute_data)->func->op_array.filename) == SUCCESS) { + zv = zend_hash_find_ex(EG(class_table), Z_STR_P(rtd_key), 1); + if (EXPECTED(zv != NULL)) { + break; + } + } + ZEND_ASSERT(EG(current_execute_data)->func->op_array.fn_flags & ZEND_ACC_PRELOADED); + zend_error_noreturn(E_ERROR, "Class %s wasn't preloaded", Z_STRVAL_P(lcname)); + return FAILURE; + } while (0); } - return FAILURE; } /* Register the derived class */ diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 0282c3c584..bb6a300a60 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -7317,8 +7317,17 @@ ZEND_VM_HANDLER(146, ZEND_DECLARE_ANON_CLASS, ANY, ANY, CACHE_SLOT) zv = zend_hash_find_ex(EG(class_table), rtd_key, 1); if (UNEXPECTED(zv == NULL)) { SAVE_OPLINE(); - ZEND_ASSERT(EX(func)->op_array.fn_flags & ZEND_ACC_PRELOADED); - zend_error_noreturn(E_ERROR, "Anonymous class wasn't preloaded"); + do { + if (zend_preload_autoload + && zend_preload_autoload(EX(func)->op_array.filename) == SUCCESS) { + zv = zend_hash_find_ex(EG(class_table), rtd_key, 1); + if (EXPECTED(zv != NULL)) { + break; + } + } + ZEND_ASSERT(EX(func)->op_array.fn_flags & ZEND_ACC_PRELOADED); + zend_error_noreturn(E_ERROR, "Anonymous class wasn't preloaded"); + } while (0); } ZEND_ASSERT(zv != NULL); ce = Z_CE_P(zv); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index d79bdb1c1f..722053bbdc 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -2449,8 +2449,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_ANON_CLASS_SPEC_HANDLE zv = zend_hash_find_ex(EG(class_table), rtd_key, 1); if (UNEXPECTED(zv == NULL)) { SAVE_OPLINE(); - ZEND_ASSERT(EX(func)->op_array.fn_flags & ZEND_ACC_PRELOADED); - zend_error_noreturn(E_ERROR, "Anonymous class wasn't preloaded"); + do { + if (zend_preload_autoload + && zend_preload_autoload(EX(func)->op_array.filename) == SUCCESS) { + zv = zend_hash_find_ex(EG(class_table), rtd_key, 1); + if (EXPECTED(zv != NULL)) { + break; + } + } + ZEND_ASSERT(EX(func)->op_array.fn_flags & ZEND_ACC_PRELOADED); + zend_error_noreturn(E_ERROR, "Anonymous class wasn't preloaded"); + } while (0); } ZEND_ASSERT(zv != NULL); ce = Z_CE_P(zv); |