From 787dfd0909e14d1061574283bcafe4c7c2961dd7 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Mon, 15 Oct 2018 11:10:23 +0200 Subject: [PATCH 01/17] Remove unused test.inc in ext/iconv/tests --- ext/iconv/tests/eucjp2iso2022jp.phpt | 1 - ext/iconv/tests/eucjp2sjis.phpt | 1 - ext/iconv/tests/eucjp2utf8.phpt | 1 - ext/iconv/tests/iconv001.phpt | 1 - ext/iconv/tests/iconv002.phpt | 1 - ext/iconv/tests/ob_iconv_handler.phpt | 1 - ext/iconv/tests/test.inc | 7 ------- ext/iconv/tests/translit-failure.phpt | 1 - ext/iconv/tests/translit-utf8.phpt | 1 - 9 files changed, 15 deletions(-) delete mode 100644 ext/iconv/tests/test.inc diff --git a/ext/iconv/tests/eucjp2iso2022jp.phpt b/ext/iconv/tests/eucjp2iso2022jp.phpt index 19cb0f736a1..6700ac91979 100644 --- a/ext/iconv/tests/eucjp2iso2022jp.phpt +++ b/ext/iconv/tests/eucjp2iso2022jp.phpt @@ -6,7 +6,6 @@ EUC-JP to ISO-2022-JP error_reporting=2039 --FILE-- diff --git a/ext/iconv/tests/translit-failure.phpt b/ext/iconv/tests/translit-failure.phpt index 2132e7e130f..1571a316c1a 100644 --- a/ext/iconv/tests/translit-failure.phpt +++ b/ext/iconv/tests/translit-failure.phpt @@ -9,7 +9,6 @@ include('skipif.inc'); error_reporting=2039 --FILE-- Date: Tue, 16 Oct 2018 10:38:19 +0200 Subject: [PATCH 02/17] Remove outdated ext/spl/examples items from .gitignore --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index f2d8d0bd293..348e71f027a 100644 --- a/.gitignore +++ b/.gitignore @@ -172,8 +172,6 @@ ext/phar/phar.phar ext/phar/phar.1 ext/phar/phar.phar.1 ext/phar/phar.php -ext/spl/examples/.htaccess -ext/spl/examples/*.phps ext/sqlite3/tests/phpsql* # ------------------------------------------------------------------------------ Windows From c54d382b2e2102bb396903cf071d09dd92f18aec Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Tue, 16 Oct 2018 11:04:39 +0200 Subject: [PATCH 03/17] [ci skip] Add magicdata.patch exception to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 348e71f027a..01b2dfb8e05 100644 --- a/.gitignore +++ b/.gitignore @@ -203,5 +203,6 @@ ext/sqlite3/tests/phpsql* # Special cases to invert previous ignore rules !ext/fileinfo/libmagic.patch +!ext/fileinfo/magicdata.patch !ext/mbstring/oniguruma.patch !ext/pcre/pcre2lib/config.h From 0df202e7ae402c04fbad0ce448da2e133b1bae70 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Tue, 16 Oct 2018 13:33:07 +0200 Subject: [PATCH 04/17] Remove obsolete buildconf.stamp from .gitignore The buildconf.stamp file was used to store particular build time information in the past and then got removed via the 6c6c0a630c48190df5fa47567699760054748f9a and the migration usage of the build/build.mk file only. --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 01b2dfb8e05..7e08d0cbba4 100644 --- a/.gitignore +++ b/.gitignore @@ -39,7 +39,6 @@ acconfig.h aclocal.m4 autom4te.cache bsd_converted -buildconf.stamp buildmk.stamp confdefs.h config.h From 265ee53b8028f1433586f0c5c6334ad297225c0f Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Tue, 16 Oct 2018 17:20:18 +0200 Subject: [PATCH 05/17] Remove configuration parser and scanners ignores The configuration-parser.c, configuration-parser.h, configuration-parser.output and configuration-scanner.c were refactored via 78194a47b7ad76aaea3bb8e91fa0f5707ae88d00 and can be removed in the .gitignore. --- .gitignore | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.gitignore b/.gitignore index 7e08d0cbba4..91477b70142 100644 --- a/.gitignore +++ b/.gitignore @@ -48,10 +48,6 @@ config.log config.nice config.status config_vars.mk -configuration-parser.c -configuration-parser.h -configuration-parser.output -configuration-scanner.c configure conftest conftest.c From 4ac9ef4a0069607c1ac948242348c6b765f9044c Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Tue, 16 Oct 2018 17:30:13 +0200 Subject: [PATCH 06/17] Remove bsd_converted from .gitignore The `bsd_converted` file was once used as a temporary locking mechanism on BSD systems builds and has been made obsolete via commit 9d9d39a0de3bec962c343051011f5a2ed7d7b242 so it can be also removed from the main .gitignore file. --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 91477b70142..fda23b93d80 100644 --- a/.gitignore +++ b/.gitignore @@ -38,7 +38,6 @@ _libs acconfig.h aclocal.m4 autom4te.cache -bsd_converted buildmk.stamp confdefs.h config.h From 066b5b78813493bf6071b4882f478d94b79d79ce Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Tue, 16 Oct 2018 18:05:06 +0200 Subject: [PATCH 07/17] Remove some obsolete config_vars.mk occurrences The `config_vars.mk` file was a part of previous *nix build system and has been removed via 9d9d39a0de3bec962c343051011f5a2ed7d7b242. --- .gitignore | 1 - scripts/dev/phpextdist | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index fda23b93d80..1ee16de4c76 100644 --- a/.gitignore +++ b/.gitignore @@ -46,7 +46,6 @@ config.h.in config.log config.nice config.status -config_vars.mk configure conftest conftest.c diff --git a/scripts/dev/phpextdist b/scripts/dev/phpextdist index 97df70020df..316a8bd5d6b 100755 --- a/scripts/dev/phpextdist +++ b/scripts/dev/phpextdist @@ -13,7 +13,7 @@ if test ! -f Makefile.in || test ! -f config.m4; then fi rm -rf modules *.lo *.o *.la config.status config.cache \ -config.log libtool php_config.h config_vars.mk Makefile +config.log libtool php_config.h Makefile myname=`basename \`pwd\`` cd .. From b33124239af07c9349cba42a516b9f00e8357445 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Tue, 16 Oct 2018 18:47:31 +0200 Subject: [PATCH 08/17] Add support for getting SKIP_TAGSTART and SKIP_WHITE options When `XML_OPTION_SKIP_TAGSTART` and `XML_OPTION_SKIP_WHITE` had been introduced[1], it had been overlooked to also support them for `xml_parser_get_option()`. We catch up on that. [1] --- NEWS | 1 + .../xml_parser_get_option_variation3.phpt | 29 +++++++++++++++++++ ext/xml/xml.c | 6 ++++ 3 files changed, 36 insertions(+) create mode 100644 ext/xml/tests/xml_parser_get_option_variation3.phpt diff --git a/NEWS b/NEWS index 3da21a1c5c8..4652c6657f5 100644 --- a/NEWS +++ b/NEWS @@ -28,6 +28,7 @@ PHP NEWS - XML: . Fixed bug #30875 (xml_parse_into_struct() does not resolve entities). (cmb) + . Add support for getting SKIP_TAGSTART and SKIP_WHITE options. (cmb) 11 Oct 2018, PHP 7.1.23 diff --git a/ext/xml/tests/xml_parser_get_option_variation3.phpt b/ext/xml/tests/xml_parser_get_option_variation3.phpt new file mode 100644 index 00000000000..839daa96dd0 --- /dev/null +++ b/ext/xml/tests/xml_parser_get_option_variation3.phpt @@ -0,0 +1,29 @@ +--TEST-- +xml_parser_get_option() with XML_OPTION_SKIP_TAGSTART and XML_OPTION_SKIP_WHITE +--SKIPIF-- + +--FILE-- + +--EXPECT-- +defaults: +int(0) +int(0) +setting: +bool(true) +bool(true) +getting: +int(7) +int(1) diff --git a/ext/xml/xml.c b/ext/xml/xml.c index b1f8cc5bd9c..373330f035b 100644 --- a/ext/xml/xml.c +++ b/ext/xml/xml.c @@ -1653,6 +1653,12 @@ PHP_FUNCTION(xml_parser_get_option) case PHP_XML_OPTION_CASE_FOLDING: RETURN_LONG(parser->case_folding); break; + case PHP_XML_OPTION_SKIP_TAGSTART: + RETURN_LONG(parser->toffset); + break; + case PHP_XML_OPTION_SKIP_WHITE: + RETURN_LONG(parser->skipwhite); + break; case PHP_XML_OPTION_TARGET_ENCODING: RETURN_STRING((char *)parser->target_encoding); break; From 1cfbb21790ff6dd4931223c5bdc18a0cebf3ffd4 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 13 Oct 2018 15:30:27 +0200 Subject: [PATCH 09/17] Classify object handlers are required/optional --- UPGRADING.INTERNALS | 23 + Zend/zend_API.c | 15 +- Zend/zend_builtin_functions.c | 3 +- Zend/zend_execute.c | 355 ++++----- Zend/zend_gc.c | 48 +- Zend/zend_object_handlers.h | 59 +- Zend/zend_objects_API.c | 28 +- Zend/zend_vm_def.h | 95 +-- Zend/zend_vm_execute.h | 1203 ++++++++++--------------------- ext/com_dotnet/com_handlers.c | 2 +- ext/reflection/php_reflection.c | 2 +- ext/spl/spl_iterators.c | 6 +- ext/standard/array.c | 4 - 13 files changed, 612 insertions(+), 1231 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index 505b3686aa9..132a2d97a75 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -7,6 +7,7 @@ PHP 7.4 INTERNALS UPGRADE NOTES d. Removed zend_check_private() e. php_win32_error_to_msg() memory management f. get_properties_for() handler / Z_OBJDEBUG_P + g. Required object handlers 2. Build system changes a. Abstract @@ -98,6 +99,28 @@ PHP 7.4 INTERNALS UPGRADE NOTES // ... zend_release_properties(ht); + g. The following object handlers are now required (must be non-NULL): + + * free_obj + * dtor_obj + * read_property + * write_property + * read_dimension + * write_dimension + * get_property_ptr_ptr + * has_property + * unset_property + * has_dimension + * unset_dimension + * get_properties + * get_method + * get_constructor + * get_class_name + * get_gc + + It is recommended to initialize object handler structures by copying the + std object handlers and only overwriting those you want to change. + ======================== 2. Build system changes ======================== diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 81a4ee76986..47a674cc133 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3114,7 +3114,7 @@ get_function_via_handler: fcc->function_handler = zend_get_call_trampoline_func(ce_org, mname, 0); call_via_handler = 1; retval = 1; - } else if (fcc->object->handlers->get_method) { + } else { fcc->function_handler = fcc->object->handlers->get_method(&fcc->object, mname, NULL); if (fcc->function_handler) { if (strict_class && @@ -3935,9 +3935,6 @@ ZEND_API void zend_update_property_ex(zend_class_entry *scope, zval *object, zen EG(fake_scope) = scope; - if (!Z_OBJ_HT_P(object)->write_property) { - zend_error_noreturn(E_CORE_ERROR, "Property %s of class %s cannot be updated", ZSTR_VAL(name), ZSTR_VAL(Z_OBJCE_P(object)->name)); - } ZVAL_STR(&property, name); Z_OBJ_HT_P(object)->write_property(object, &property, value, NULL); @@ -3952,9 +3949,6 @@ ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const EG(fake_scope) = scope; - if (!Z_OBJ_HT_P(object)->write_property) { - zend_error_noreturn(E_CORE_ERROR, "Property %s of class %s cannot be updated", name, ZSTR_VAL(Z_OBJCE_P(object)->name)); - } ZVAL_STRINGL(&property, name, name_length); Z_OBJ_HT_P(object)->write_property(object, &property, value, NULL); zval_ptr_dtor(&property); @@ -3979,9 +3973,6 @@ ZEND_API void zend_unset_property(zend_class_entry *scope, zval *object, const c EG(fake_scope) = scope; - if (!Z_OBJ_HT_P(object)->unset_property) { - zend_error_noreturn(E_CORE_ERROR, "Property %s of class %s cannot be unset", name, ZSTR_VAL(Z_OBJCE_P(object)->name)); - } ZVAL_STRINGL(&property, name, name_length); Z_OBJ_HT_P(object)->unset_property(object, &property, 0); zval_ptr_dtor(&property); @@ -4143,10 +4134,6 @@ ZEND_API zval *zend_read_property_ex(zend_class_entry *scope, zval *object, zend EG(fake_scope) = scope; - if (!Z_OBJ_HT_P(object)->read_property) { - zend_error_noreturn(E_CORE_ERROR, "Property %s of class %s cannot be read", ZSTR_VAL(name), ZSTR_VAL(Z_OBJCE_P(object)->name)); - } - ZVAL_STR(&property, name); value = Z_OBJ_HT_P(object)->read_property(object, &property, silent?BP_VAR_IS:BP_VAR_R, NULL, rv); diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 364d478ab73..1ff32cc355a 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -1338,7 +1338,7 @@ ZEND_FUNCTION(method_exists) if (zend_hash_exists(&ce->function_table, lcname)) { zend_string_release_ex(lcname, 0); RETURN_TRUE; - } else if (Z_TYPE_P(klass) == IS_OBJECT && Z_OBJ_HT_P(klass)->get_method != NULL) { + } else if (Z_TYPE_P(klass) == IS_OBJECT) { zend_object *obj = Z_OBJ_P(klass); zend_function *func = Z_OBJ_HT_P(klass)->get_method(&obj, method_name, NULL); if (func != NULL) { @@ -1401,7 +1401,6 @@ ZEND_FUNCTION(property_exists) ZVAL_STR(&property_z, property); if (Z_TYPE_P(object) == IS_OBJECT && - Z_OBJ_HANDLER_P(object, has_property) && Z_OBJ_HANDLER_P(object, has_property)(object, &property_z, 2, NULL)) { RETURN_TRUE; } diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index cbaa53f4e10..66ff7abfcd3 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -625,17 +625,6 @@ static zend_never_inline ZEND_COLD int zend_wrong_assign_to_variable_reference(z return 1; } -static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_wrong_property_assignment(zval *property OPLINE_DC EXECUTE_DATA_DC) -{ - zend_string *tmp_property_name; - zend_string *property_name = zval_get_tmp_string(property, &tmp_property_name); - zend_error(E_WARNING, "Attempt to assign property '%s' of non-object", ZSTR_VAL(property_name)); - zend_tmp_string_release(tmp_property_name); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } -} - /* this should modify object only if it's empty */ static zend_never_inline ZEND_COLD int ZEND_FASTCALL make_real_object(zval *object, zval *property OPLINE_DC EXECUTE_DATA_DC) { @@ -1112,14 +1101,6 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_illegal_offset(void) static zend_never_inline void zend_assign_to_object_dim(zval *object, zval *dim, zval *value OPLINE_DC EXECUTE_DATA_DC) { - if (UNEXPECTED(!Z_OBJ_HT_P(object)->write_dimension)) { - zend_use_object_as_array(); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - } - return; - } - Z_OBJ_HT_P(object)->write_dimension(object, dim, value); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { @@ -1132,8 +1113,7 @@ static zend_never_inline void zend_binary_assign_op_obj_dim(zval *object, zval * zval *z; zval rv, res; - if (Z_OBJ_HT_P(object)->read_dimension && - (z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv)) != NULL) { + if ((z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv)) != NULL) { if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) { zval rv2; @@ -1335,22 +1315,6 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_wrong_property_read(z zend_tmp_string_release(tmp_property_name); } -static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_wrong_property_unset(zval *property) -{ - zend_string *tmp_property_name; - zend_string *property_name = zval_get_tmp_string(property, &tmp_property_name); - zend_error(E_NOTICE, "Trying to unset property '%s' of non-object", ZSTR_VAL(property_name)); - zend_tmp_string_release(tmp_property_name); -} - -static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_wrong_property_check(zval *property) -{ - zend_string *tmp_property_name; - zend_string *property_name = zval_get_tmp_string(property, &tmp_property_name); - zend_error(E_NOTICE, "Trying to check property '%s' of non-object", ZSTR_VAL(property_name)); - zend_tmp_string_release(tmp_property_name); -} - static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_deprecated_function(const zend_function *fbc) { zend_error(E_DEPRECATED, "Function %s%s%s() is deprecated", @@ -1425,93 +1389,80 @@ static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim, static zend_never_inline void zend_post_incdec_overloaded_property(zval *object, zval *property, void **cache_slot, int inc OPLINE_DC EXECUTE_DATA_DC) { - if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval rv, obj; - zval *z; - zval z_copy; + zval rv, obj; + zval *z; + zval z_copy; - ZVAL_OBJ(&obj, Z_OBJ_P(object)); - Z_ADDREF(obj); - z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv); - if (UNEXPECTED(EG(exception))) { - OBJ_RELEASE(Z_OBJ(obj)); - ZVAL_UNDEF(EX_VAR(opline->result.var)); - return; - } - - if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { - zval rv2; - zval *value = Z_OBJ_HT_P(z)->get(z, &rv2); - if (z == &rv) { - zval_ptr_dtor(&rv); - } - ZVAL_COPY_VALUE(z, value); - } - - ZVAL_COPY_DEREF(&z_copy, z); - ZVAL_COPY(EX_VAR(opline->result.var), &z_copy); - if (inc) { - increment_function(&z_copy); - } else { - decrement_function(&z_copy); - } - Z_OBJ_HT(obj)->write_property(&obj, property, &z_copy, cache_slot); + ZVAL_OBJ(&obj, Z_OBJ_P(object)); + Z_ADDREF(obj); + z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv); + if (UNEXPECTED(EG(exception))) { OBJ_RELEASE(Z_OBJ(obj)); - zval_ptr_dtor(&z_copy); - zval_ptr_dtor(z); - } else { - zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - ZVAL_NULL(EX_VAR(opline->result.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); + return; } + + if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { + zval rv2; + zval *value = Z_OBJ_HT_P(z)->get(z, &rv2); + if (z == &rv) { + zval_ptr_dtor(&rv); + } + ZVAL_COPY_VALUE(z, value); + } + + ZVAL_COPY_DEREF(&z_copy, z); + ZVAL_COPY(EX_VAR(opline->result.var), &z_copy); + if (inc) { + increment_function(&z_copy); + } else { + decrement_function(&z_copy); + } + Z_OBJ_HT(obj)->write_property(&obj, property, &z_copy, cache_slot); + OBJ_RELEASE(Z_OBJ(obj)); + zval_ptr_dtor(&z_copy); + zval_ptr_dtor(z); } static zend_never_inline void zend_pre_incdec_overloaded_property(zval *object, zval *property, void **cache_slot, int inc OPLINE_DC EXECUTE_DATA_DC) { zval rv; + zval *z, obj; + zval z_copy; - if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { - zval *z, obj; - zval z_copy; - - ZVAL_OBJ(&obj, Z_OBJ_P(object)); - Z_ADDREF(obj); - z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv); - if (UNEXPECTED(EG(exception))) { - OBJ_RELEASE(Z_OBJ(obj)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); - } - return; - } - - if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { - zval rv2; - zval *value = Z_OBJ_HT_P(z)->get(z, &rv2); - - if (z == &rv) { - zval_ptr_dtor(&rv); - } - ZVAL_COPY_VALUE(z, value); - } - ZVAL_COPY_DEREF(&z_copy, z); - if (inc) { - increment_function(&z_copy); - } else { - decrement_function(&z_copy); - } - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), &z_copy); - } - Z_OBJ_HT(obj)->write_property(&obj, property, &z_copy, cache_slot); + ZVAL_OBJ(&obj, Z_OBJ_P(object)); + Z_ADDREF(obj); + z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv); + if (UNEXPECTED(EG(exception))) { OBJ_RELEASE(Z_OBJ(obj)); - zval_ptr_dtor(&z_copy); - zval_ptr_dtor(z); - } else { - zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } + return; } + + if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) { + zval rv2; + zval *value = Z_OBJ_HT_P(z)->get(z, &rv2); + + if (z == &rv) { + zval_ptr_dtor(&rv); + } + ZVAL_COPY_VALUE(z, value); + } + ZVAL_COPY_DEREF(&z_copy, z); + if (inc) { + increment_function(&z_copy); + } else { + decrement_function(&z_copy); + } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), &z_copy); + } + Z_OBJ_HT(obj)->write_property(&obj, property, &z_copy, cache_slot); + OBJ_RELEASE(Z_OBJ(obj)); + zval_ptr_dtor(&z_copy); + zval_ptr_dtor(z); } static zend_never_inline void zend_assign_op_overloaded_property(zval *object, zval *property, void **cache_slot, zval *value, binary_op_type binary_op OPLINE_DC EXECUTE_DATA_DC) @@ -1521,38 +1472,31 @@ static zend_never_inline void zend_assign_op_overloaded_property(zval *object, z ZVAL_OBJ(&obj, Z_OBJ_P(object)); Z_ADDREF(obj); - if (EXPECTED(Z_OBJ_HT(obj)->read_property)) { - z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv); - if (UNEXPECTED(EG(exception))) { - OBJ_RELEASE(Z_OBJ(obj)); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_UNDEF(EX_VAR(opline->result.var)); - } - return; - } - if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) { - zval rv2; - zval *value = Z_OBJ_HT_P(z)->get(z, &rv2); - - if (z == &rv) { - zval_ptr_dtor(&rv); - } - ZVAL_COPY_VALUE(z, value); - } - if (binary_op(&res, z, value) == SUCCESS) { - Z_OBJ_HT(obj)->write_property(&obj, property, &res, cache_slot); - } + z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv); + if (UNEXPECTED(EG(exception))) { + OBJ_RELEASE(Z_OBJ(obj)); if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_COPY(EX_VAR(opline->result.var), &res); - } - zval_ptr_dtor(z); - zval_ptr_dtor(&res); - } else { - zend_error(E_WARNING, "Attempt to assign property of non-object"); - if (UNEXPECTED(RETURN_VALUE_USED(opline))) { - ZVAL_NULL(EX_VAR(opline->result.var)); + ZVAL_UNDEF(EX_VAR(opline->result.var)); } + return; } + if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) { + zval rv2; + zval *value = Z_OBJ_HT_P(z)->get(z, &rv2); + + if (z == &rv) { + zval_ptr_dtor(&rv); + } + ZVAL_COPY_VALUE(z, value); + } + if (binary_op(&res, z, value) == SUCCESS) { + Z_OBJ_HT(obj)->write_property(&obj, property, &res, cache_slot); + } + if (UNEXPECTED(RETURN_VALUE_USED(opline))) { + ZVAL_COPY(EX_VAR(opline->result.var), &res); + } + zval_ptr_dtor(z); + zval_ptr_dtor(&res); OBJ_RELEASE(Z_OBJ(obj)); } @@ -1660,16 +1604,6 @@ static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_use_new_element_for_s zend_throw_error(NULL, "[] operator not supported for strings"); } -static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_access_undefined_propery_in_overloaded_object(void) -{ - zend_throw_error(NULL, "Cannot access undefined property for object with overloaded property access"); -} - -static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_unsupported_property_reference(void) -{ - zend_error(E_WARNING, "This object doesn't support property references"); -} - static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht, const zval *dim, int dim_type, int type EXECUTE_DATA_DC) { zval *retval = NULL; @@ -1844,39 +1778,34 @@ fetch_from_array: zval_undefined_cv(EX(opline)->op2.var EXECUTE_DATA_CC); dim = &EG(uninitialized_zval); } - if (!Z_OBJ_HT_P(container)->read_dimension) { - zend_use_object_as_array(); - ZVAL_ERROR(result); - } else { - if (dim_type == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - retval = Z_OBJ_HT_P(container)->read_dimension(container, dim, type, result); + if (dim_type == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + retval = Z_OBJ_HT_P(container)->read_dimension(container, dim, type, result); - if (UNEXPECTED(retval == &EG(uninitialized_zval))) { - zend_class_entry *ce = Z_OBJCE_P(container); + if (UNEXPECTED(retval == &EG(uninitialized_zval))) { + zend_class_entry *ce = Z_OBJCE_P(container); - ZVAL_NULL(result); - zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ZSTR_VAL(ce->name)); - } else if (EXPECTED(retval && Z_TYPE_P(retval) != IS_UNDEF)) { - if (!Z_ISREF_P(retval)) { - if (result != retval) { - ZVAL_COPY(result, retval); - retval = result; - } - if (Z_TYPE_P(retval) != IS_OBJECT) { - zend_class_entry *ce = Z_OBJCE_P(container); - zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ZSTR_VAL(ce->name)); - } - } else if (UNEXPECTED(Z_REFCOUNT_P(retval) == 1)) { - ZVAL_UNREF(retval); - } + ZVAL_NULL(result); + zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ZSTR_VAL(ce->name)); + } else if (EXPECTED(retval && Z_TYPE_P(retval) != IS_UNDEF)) { + if (!Z_ISREF_P(retval)) { if (result != retval) { - ZVAL_INDIRECT(result, retval); + ZVAL_COPY(result, retval); + retval = result; } - } else { - ZVAL_ERROR(result); + if (Z_TYPE_P(retval) != IS_OBJECT) { + zend_class_entry *ce = Z_OBJCE_P(container); + zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ZSTR_VAL(ce->name)); + } + } else if (UNEXPECTED(Z_REFCOUNT_P(retval) == 1)) { + ZVAL_UNREF(retval); } + if (result != retval) { + ZVAL_INDIRECT(result, retval); + } + } else { + ZVAL_ERROR(result); } } else { if (type != BP_VAR_W && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { @@ -2004,25 +1933,20 @@ try_string_offset: zval_undefined_cv(EX(opline)->op2.var EXECUTE_DATA_CC); dim = &EG(uninitialized_zval); } - if (!Z_OBJ_HT_P(container)->read_dimension) { - zend_use_object_as_array(); - ZVAL_NULL(result); - } else { - if (dim_type == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { - dim++; - } - retval = Z_OBJ_HT_P(container)->read_dimension(container, dim, type, result); + if (dim_type == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) { + dim++; + } + retval = Z_OBJ_HT_P(container)->read_dimension(container, dim, type, result); - ZEND_ASSERT(result != NULL); - if (retval) { - if (result != retval) { - ZVAL_COPY_DEREF(result, retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(result); - } - } else { - ZVAL_NULL(result); + ZEND_ASSERT(result != NULL); + if (retval) { + if (result != retval) { + ZVAL_COPY_DEREF(result, retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(result); } + } else { + ZVAL_NULL(result); } } else { if (type != BP_VAR_IS && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { @@ -2101,12 +2025,7 @@ static zend_never_inline int ZEND_FASTCALL zend_isset_dim_slow(zval *container, } if (/*OP1_TYPE != IS_CONST &&*/ EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) { - return Z_OBJ_HT_P(container)->has_dimension(container, offset, 0); - } else { - zend_use_object_as_array(); - return 0; - } + return Z_OBJ_HT_P(container)->has_dimension(container, offset, 0); } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */ zend_long lval; @@ -2146,12 +2065,7 @@ static zend_never_inline int ZEND_FASTCALL zend_isempty_dim_slow(zval *container } if (/*OP1_TYPE != IS_CONST &&*/ EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (EXPECTED(Z_OBJ_HT_P(container)->has_dimension)) { - return !Z_OBJ_HT_P(container)->has_dimension(container, offset, 1); - } else { - zend_use_object_as_array(); - return 1; - } + return !Z_OBJ_HT_P(container)->has_dimension(container, offset, 1); } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */ zend_long lval; @@ -2185,6 +2099,7 @@ str_offset: static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, void **cache_slot, int type OPLINE_DC) { + zval *ptr; if (container_op_type != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { do { if (Z_ISREF_P(container)) { @@ -2228,29 +2143,17 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c } } } - if (EXPECTED(Z_OBJ_HT_P(container)->get_property_ptr_ptr)) { - zval *ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, type, cache_slot); - if (NULL == ptr) { - if (EXPECTED(Z_OBJ_HT_P(container)->read_property)) { -use_read_property: - ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result); - if (ptr != result) { - ZVAL_INDIRECT(result, ptr); - } else if (UNEXPECTED(Z_ISREF_P(ptr) && Z_REFCOUNT_P(ptr) == 1)) { - ZVAL_UNREF(ptr); - } - } else { - zend_access_undefined_propery_in_overloaded_object(); - ZVAL_ERROR(result); - } - } else { + + ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, type, cache_slot); + if (NULL == ptr) { + ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result); + if (ptr != result) { ZVAL_INDIRECT(result, ptr); + } else if (UNEXPECTED(Z_ISREF_P(ptr) && Z_REFCOUNT_P(ptr) == 1)) { + ZVAL_UNREF(ptr); } - } else if (EXPECTED(Z_OBJ_HT_P(container)->read_property)) { - goto use_read_property; } else { - zend_unsupported_property_reference(); - ZVAL_ERROR(result); + ZVAL_INDIRECT(result, ptr); } } diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index 1732fdefc40..15a594da606 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -617,17 +617,15 @@ tail_call: GC_REF_SET_BLACK(ref); if (GC_TYPE(ref) == IS_OBJECT) { - zend_object_get_gc_t get_gc; zend_object *obj = (zend_object*)ref; - if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED) && - (get_gc = obj->handlers->get_gc) != NULL)) { + if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED))) { int n; zval *zv, *end; zval tmp; ZVAL_OBJ(&tmp, obj); - ht = get_gc(&tmp, &zv, &n); + ht = obj->handlers->get_gc(&tmp, &zv, &n); end = zv + n; if (EXPECTED(!ht)) { if (!n) return; @@ -727,17 +725,15 @@ tail_call: GC_REF_SET_COLOR(ref, GC_GREY); if (GC_TYPE(ref) == IS_OBJECT) { - zend_object_get_gc_t get_gc; zend_object *obj = (zend_object*)ref; - if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED) && - (get_gc = obj->handlers->get_gc) != NULL)) { + if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED))) { int n; zval *zv, *end; zval tmp; ZVAL_OBJ(&tmp, obj); - ht = get_gc(&tmp, &zv, &n); + ht = obj->handlers->get_gc(&tmp, &zv, &n); end = zv + n; if (EXPECTED(!ht)) { if (!n) return; @@ -883,17 +879,15 @@ tail_call: } else { GC_REF_SET_COLOR(ref, GC_WHITE); if (GC_TYPE(ref) == IS_OBJECT) { - zend_object_get_gc_t get_gc; zend_object *obj = (zend_object*)ref; - if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED) && - (get_gc = obj->handlers->get_gc) != NULL)) { + if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED))) { int n; zval *zv, *end; zval tmp; ZVAL_OBJ(&tmp, obj); - ht = get_gc(&tmp, &zv, &n); + ht = obj->handlers->get_gc(&tmp, &zv, &n); end = zv + n; if (EXPECTED(!ht)) { if (!n) return; @@ -1023,11 +1017,9 @@ tail_call: } if (GC_TYPE(ref) == IS_OBJECT) { - zend_object_get_gc_t get_gc; zend_object *obj = (zend_object*)ref; - if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED) && - (get_gc = obj->handlers->get_gc) != NULL)) { + if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED))) { int n; zval *zv, *end; zval tmp; @@ -1036,13 +1028,12 @@ tail_call: if (!GC_INFO(ref)) { gc_add_garbage(ref); } - if (obj->handlers->dtor_obj && - ((obj->handlers->dtor_obj != zend_objects_destroy_object) || - (obj->ce->destructor != NULL))) { + if (obj->handlers->dtor_obj != zend_objects_destroy_object || + obj->ce->destructor != NULL) { *flags |= GC_HAS_DESTRUCTORS; } ZVAL_OBJ(&tmp, obj); - ht = get_gc(&tmp, &zv, &n); + ht = obj->handlers->get_gc(&tmp, &zv, &n); end = zv + n; if (EXPECTED(!ht)) { if (!n) return count; @@ -1193,17 +1184,15 @@ tail_call: } if (GC_TYPE(ref) == IS_OBJECT) { - zend_object_get_gc_t get_gc; zend_object *obj = (zend_object*)ref; - if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED) && - (get_gc = obj->handlers->get_gc) != NULL)) { + if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED))) { int n; zval *zv, *end; zval tmp; ZVAL_OBJ(&tmp, obj); - ht = get_gc(&tmp, &zv, &n); + ht = obj->handlers->get_gc(&tmp, &zv, &n); end = zv + n; if (EXPECTED(!ht)) { if (!n) return; @@ -1341,9 +1330,8 @@ ZEND_API int zend_gc_collect_cycles(void) GC_TRACE_REF(obj, "calling destructor"); GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED); - if (obj->handlers->dtor_obj - && (obj->handlers->dtor_obj != zend_objects_destroy_object - || obj->ce->destructor)) { + if (obj->handlers->dtor_obj != zend_objects_destroy_object + || obj->ce->destructor) { GC_ADDREF(obj); obj->handlers->dtor_obj(obj); GC_DELREF(obj); @@ -1392,11 +1380,9 @@ ZEND_API int zend_gc_collect_cycles(void) (GC_TYPE_INFO(obj) & ~GC_TYPE_MASK); if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) { GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED); - if (obj->handlers->free_obj) { - GC_ADDREF(obj); - obj->handlers->free_obj(obj); - GC_DELREF(obj); - } + GC_ADDREF(obj); + obj->handlers->free_obj(obj); + GC_DELREF(obj); } ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(obj->handle); diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 83a22c4d2b3..2f94ba1cb6f 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -153,36 +153,35 @@ typedef int (*zend_object_do_operation_t)(zend_uchar opcode, zval *result, zval struct _zend_object_handlers { /* offset of real object header (usually zero) */ int offset; - /* general object functions */ - zend_object_free_obj_t free_obj; - zend_object_dtor_obj_t dtor_obj; - zend_object_clone_obj_t clone_obj; - /* individual object functions */ - zend_object_read_property_t read_property; - zend_object_write_property_t write_property; - zend_object_read_dimension_t read_dimension; - zend_object_write_dimension_t write_dimension; - zend_object_get_property_ptr_ptr_t get_property_ptr_ptr; - zend_object_get_t get; - zend_object_set_t set; - zend_object_has_property_t has_property; - zend_object_unset_property_t unset_property; - zend_object_has_dimension_t has_dimension; - zend_object_unset_dimension_t unset_dimension; - zend_object_get_properties_t get_properties; /* required */ - zend_object_get_method_t get_method; - zend_object_call_method_t call_method; - zend_object_get_constructor_t get_constructor; - zend_object_get_class_name_t get_class_name; - zend_object_compare_t compare_objects; - zend_object_cast_t cast_object; - zend_object_count_elements_t count_elements; - zend_object_get_debug_info_t get_debug_info; - zend_object_get_closure_t get_closure; - zend_object_get_gc_t get_gc; - zend_object_do_operation_t do_operation; - zend_object_compare_zvals_t compare; - zend_object_get_properties_for_t get_properties_for; /* optional */ + /* object handlers */ + zend_object_free_obj_t free_obj; /* required */ + zend_object_dtor_obj_t dtor_obj; /* required */ + zend_object_clone_obj_t clone_obj; /* optional */ + zend_object_read_property_t read_property; /* required */ + zend_object_write_property_t write_property; /* required */ + zend_object_read_dimension_t read_dimension; /* required */ + zend_object_write_dimension_t write_dimension; /* required */ + zend_object_get_property_ptr_ptr_t get_property_ptr_ptr; /* required */ + zend_object_get_t get; /* optional */ + zend_object_set_t set; /* optional */ + zend_object_has_property_t has_property; /* required */ + zend_object_unset_property_t unset_property; /* required */ + zend_object_has_dimension_t has_dimension; /* required */ + zend_object_unset_dimension_t unset_dimension; /* required */ + zend_object_get_properties_t get_properties; /* required */ + zend_object_get_method_t get_method; /* required */ + zend_object_call_method_t call_method; /* optional */ + zend_object_get_constructor_t get_constructor; /* required */ + zend_object_get_class_name_t get_class_name; /* required */ + zend_object_compare_t compare_objects; /* optional */ + zend_object_cast_t cast_object; /* optional */ + zend_object_count_elements_t count_elements; /* optional */ + zend_object_get_debug_info_t get_debug_info; /* optional */ + zend_object_get_closure_t get_closure; /* optional */ + zend_object_get_gc_t get_gc; /* required */ + zend_object_do_operation_t do_operation; /* optional */ + zend_object_compare_zvals_t compare; /* optional */ + zend_object_get_properties_for_t get_properties_for; /* optional */ }; BEGIN_EXTERN_C() diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c index 672a580caa6..23c88424118 100644 --- a/Zend/zend_objects_API.c +++ b/Zend/zend_objects_API.c @@ -49,9 +49,8 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_call_destructors(zend_objects_sto if (!(OBJ_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) { GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED); - if (obj->handlers->dtor_obj - && (obj->handlers->dtor_obj != zend_objects_destroy_object - || obj->ce->destructor)) { + if (obj->handlers->dtor_obj != zend_objects_destroy_object + || obj->ce->destructor) { GC_ADDREF(obj); obj->handlers->dtor_obj(obj); GC_DELREF(obj); @@ -98,7 +97,7 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_free_object_storage(zend_objects_ if (IS_OBJ_VALID(obj)) { if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) { GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED); - if (obj->handlers->free_obj && obj->handlers->free_obj != zend_object_std_dtor) { + if (obj->handlers->free_obj != zend_object_std_dtor) { GC_ADDREF(obj); obj->handlers->free_obj(obj); GC_DELREF(obj); @@ -113,11 +112,9 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_free_object_storage(zend_objects_ if (IS_OBJ_VALID(obj)) { if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) { GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED); - if (obj->handlers->free_obj) { - GC_ADDREF(obj); - obj->handlers->free_obj(obj); - GC_DELREF(obj); - } + GC_ADDREF(obj); + obj->handlers->free_obj(obj); + GC_DELREF(obj); } } } while (obj_ptr != end); @@ -163,9 +160,8 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object) /* {{{ * if (!(OBJ_FLAGS(object) & IS_OBJ_DESTRUCTOR_CALLED)) { GC_ADD_FLAGS(object, IS_OBJ_DESTRUCTOR_CALLED); - if (object->handlers->dtor_obj - && (object->handlers->dtor_obj != zend_objects_destroy_object - || object->ce->destructor)) { + if (object->handlers->dtor_obj != zend_objects_destroy_object + || object->ce->destructor) { GC_ADDREF(object); object->handlers->dtor_obj(object); GC_DELREF(object); @@ -179,11 +175,9 @@ ZEND_API void ZEND_FASTCALL zend_objects_store_del(zend_object *object) /* {{{ * EG(objects_store).object_buckets[handle] = SET_OBJ_INVALID(object); if (!(OBJ_FLAGS(object) & IS_OBJ_FREE_CALLED)) { GC_ADD_FLAGS(object, IS_OBJ_FREE_CALLED); - if (object->handlers->free_obj) { - GC_ADDREF(object); - object->handlers->free_obj(object); - GC_DELREF(object); - } + GC_ADDREF(object); + object->handlers->free_obj(object); + GC_DELREF(object); } ptr = ((char*)object) - object->handlers->offset; GC_REMOVE_FROM_BUFFER(object); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 36fb9a1779b..23332f94158 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -822,8 +822,7 @@ ZEND_VM_HELPER(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, /* here we are sure we are dealing with an object */ ZEND_VM_C_LABEL(assign_op_object): - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -1084,8 +1083,7 @@ ZEND_VM_HELPER(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, /* here we are sure we are dealing with an object */ ZEND_VM_C_LABEL(pre_incdec_object): - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -1162,8 +1160,7 @@ ZEND_VM_HELPER(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|CV, /* here we are sure we are dealing with an object */ ZEND_VM_C_LABEL(post_incdec_object): - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -1795,7 +1792,9 @@ ZEND_VM_HOT_OBJ_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMPVAR|UNUSED|THIS|CV, CONST if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - ZEND_VM_C_GOTO(fetch_obj_r_no_object); + zend_wrong_property_read(offset); + ZVAL_NULL(EX_VAR(opline->result.var)); + ZEND_VM_C_GOTO(fetch_obj_r_finish); } while (0); } @@ -1847,21 +1846,16 @@ ZEND_VM_HOT_OBJ_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMPVAR|UNUSED|THIS|CV, CONST GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -ZEND_VM_C_LABEL(fetch_obj_r_no_object): - zend_wrong_property_read(offset); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); } } while (0); +ZEND_VM_C_LABEL(fetch_obj_r_finish): FREE_OP2(); FREE_OP1(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -1939,7 +1933,8 @@ ZEND_VM_COLD_CONST_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, C break; } } - ZEND_VM_C_GOTO(fetch_obj_is_no_object); + ZVAL_NULL(EX_VAR(opline->result.var)); + ZEND_VM_C_GOTO(fetch_obj_is_finish); } while (0); } @@ -1989,19 +1984,14 @@ ZEND_VM_COLD_CONST_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, C } } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -ZEND_VM_C_LABEL(fetch_obj_is_no_object): - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); } } while (0); +ZEND_VM_C_LABEL(fetch_obj_is_finish): FREE_OP2(); FREE_OP1(); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -2179,12 +2169,6 @@ ZEND_VM_C_LABEL(fast_assign_obj): } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - FREE_OP_DATA(); - ZEND_VM_C_GOTO(exit_assign_obj); - } - if (OP_DATA_TYPE == IS_CV || OP_DATA_TYPE == IS_VAR) { ZVAL_DEREF(value); } @@ -3072,13 +3056,6 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, } else { zend_object *orig_obj = obj; - if (UNEXPECTED(obj->handlers->get_method == NULL)) { - zend_throw_error(NULL, "Object does not support method calls"); - FREE_OP2(); - FREE_OP1(); - HANDLE_EXCEPTION(); - } - if (OP2_TYPE == IS_CONST) { function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); } @@ -5599,14 +5576,10 @@ ZEND_VM_C_LABEL(num_index_dim): offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { - zend_use_object_as_array(); - } else { - if (OP2_TYPE == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - Z_OBJ_HT_P(container)->unset_dimension(container, offset); + if (OP2_TYPE == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; } + Z_OBJ_HT_P(container)->unset_dimension(container, offset); } else if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { zend_throw_error(NULL, "Cannot unset string offsets"); } @@ -5642,11 +5615,7 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_S break; } } - if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - } else { - zend_wrong_property_unset(offset); - } + Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } while (0); FREE_OP2(); @@ -6367,22 +6336,20 @@ ZEND_VM_COLD_CONST_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - ZEND_VM_C_GOTO(isset_no_object); + result = (opline->extended_value & ZEND_ISEMPTY); + ZEND_VM_C_GOTO(isset_object_finish); } } else { - ZEND_VM_C_GOTO(isset_no_object); + result = (opline->extended_value & ZEND_ISEMPTY); + ZEND_VM_C_GOTO(isset_object_finish); } } - if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { - zend_wrong_property_check(offset); -ZEND_VM_C_LABEL(isset_no_object): - result = (opline->extended_value & ZEND_ISEMPTY); - } else { - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - } + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + +ZEND_VM_C_LABEL(isset_object_finish): FREE_OP2(); FREE_OP1(); ZEND_VM_SMART_BRANCH(result, 1); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 03d767247b6..69e15a9fd96 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -4652,7 +4652,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - goto fetch_obj_r_no_object; + zend_wrong_property_read(offset); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; } while (0); } @@ -4704,21 +4706,17 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_ GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_r_no_object: - zend_wrong_property_read(offset); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); } } while (0); +fetch_obj_r_finish: + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -4750,7 +4748,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC break; } } - goto fetch_obj_is_no_object; + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; } while (0); } @@ -4800,19 +4799,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC } } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_is_no_object: - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); } } while (0); +fetch_obj_is_finish: + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -5039,13 +5034,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ } else { zend_object *orig_obj = obj; - if (UNEXPECTED(obj->handlers->get_method == NULL)) { - zend_throw_error(NULL, "Object does not support method calls"); - - - HANDLE_EXCEPTION(); - } - if (IS_CONST == IS_CONST) { function_name = RT_CONSTANT(opline, opline->op2); } @@ -5723,21 +5711,20 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PRO if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } else { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } - if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { - zend_wrong_property_check(offset); -isset_no_object: - result = (opline->extended_value & ZEND_ISEMPTY); - } else { - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - } + + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + +isset_object_finish: ZEND_VM_SMART_BRANCH(result, 1); @@ -6826,7 +6813,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - goto fetch_obj_r_no_object; + zend_wrong_property_read(offset); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; } while (0); } @@ -6878,21 +6867,16 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_ GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_r_no_object: - zend_wrong_property_read(offset); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); } } while (0); +fetch_obj_r_finish: zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -6925,7 +6909,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC break; } } - goto fetch_obj_is_no_object; + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; } while (0); } @@ -6975,19 +6960,14 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC } } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_is_no_object: - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); } } while (0); +fetch_obj_is_finish: zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -7215,13 +7195,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ } else { zend_object *orig_obj = obj; - if (UNEXPECTED(obj->handlers->get_method == NULL)) { - zend_throw_error(NULL, "Object does not support method calls"); - zval_ptr_dtor_nogc(free_op2); - - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); } @@ -7699,22 +7672,20 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PRO if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } else { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } - if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { - zend_wrong_property_check(offset); -isset_no_object: - result = (opline->extended_value & ZEND_ISEMPTY); - } else { - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - } + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + +isset_object_finish: zval_ptr_dtor_nogc(free_op2); ZEND_VM_SMART_BRANCH(result, 1); @@ -9924,7 +9895,9 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - goto fetch_obj_r_no_object; + zend_wrong_property_read(offset); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; } while (0); } @@ -9976,21 +9949,17 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_ GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_r_no_object: - zend_wrong_property_read(offset); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); } } while (0); +fetch_obj_r_finish: + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -10022,7 +9991,8 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC break; } } - goto fetch_obj_is_no_object; + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; } while (0); } @@ -10072,19 +10042,15 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC } } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_is_no_object: - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); } } while (0); +fetch_obj_is_finish: + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -10311,13 +10277,6 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_ } else { zend_object *orig_obj = obj; - if (UNEXPECTED(obj->handlers->get_method == NULL)) { - zend_throw_error(NULL, "Object does not support method calls"); - - - HANDLE_EXCEPTION(); - } - if (IS_CV == IS_CONST) { function_name = EX_VAR(opline->op2.var); } @@ -10794,21 +10753,20 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PRO if ((IS_CONST & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } else { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } - if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { - zend_wrong_property_check(offset); -isset_no_object: - result = (opline->extended_value & ZEND_ISEMPTY); - } else { - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - } + + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + +isset_object_finish: ZEND_VM_SMART_BRANCH(result, 1); @@ -13669,7 +13627,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - goto fetch_obj_r_no_object; + zend_wrong_property_read(offset); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; } while (0); } @@ -13721,21 +13681,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CONST_ GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_r_no_object: - zend_wrong_property_read(offset); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); } } while (0); +fetch_obj_r_finish: + zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -13767,7 +13723,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST break; } } - goto fetch_obj_is_no_object; + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; } while (0); } @@ -13817,19 +13774,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CONST } } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_is_no_object: - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); } } while (0); +fetch_obj_is_finish: + zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -14029,13 +13982,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C } else { zend_object *orig_obj = obj; - if (UNEXPECTED(obj->handlers->get_method == NULL)) { - zend_throw_error(NULL, "Object does not support method calls"); - - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - if (IS_CONST == IS_CONST) { function_name = RT_CONSTANT(opline, opline->op2); } @@ -14373,21 +14319,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TM if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } else { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } - if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { - zend_wrong_property_check(offset); -isset_no_object: - result = (opline->extended_value & ZEND_ISEMPTY); - } else { - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - } + + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + +isset_object_finish: zval_ptr_dtor_nogc(free_op1); ZEND_VM_SMART_BRANCH(result, 1); @@ -15277,7 +15222,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - goto fetch_obj_r_no_object; + zend_wrong_property_read(offset); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; } while (0); } @@ -15329,21 +15276,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_TMPVAR GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_r_no_object: - zend_wrong_property_read(offset); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); } } while (0); +fetch_obj_r_finish: zval_ptr_dtor_nogc(free_op2); zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -15376,7 +15318,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVA break; } } - goto fetch_obj_is_no_object; + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; } while (0); } @@ -15426,19 +15369,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_TMPVA } } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_is_no_object: - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); } } while (0); +fetch_obj_is_finish: zval_ptr_dtor_nogc(free_op2); zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -15639,13 +15577,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T } else { zend_object *orig_obj = obj; - if (UNEXPECTED(obj->handlers->get_method == NULL)) { - zend_throw_error(NULL, "Object does not support method calls"); - zval_ptr_dtor_nogc(free_op2); - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); } @@ -15852,22 +15783,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TM if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } else { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } - if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { - zend_wrong_property_check(offset); -isset_no_object: - result = (opline->extended_value & ZEND_ISEMPTY); - } else { - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - } + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + +isset_object_finish: zval_ptr_dtor_nogc(free_op2); zval_ptr_dtor_nogc(free_op1); ZEND_VM_SMART_BRANCH(result, 1); @@ -17156,7 +17085,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HAN if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - goto fetch_obj_r_no_object; + zend_wrong_property_read(offset); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; } while (0); } @@ -17208,21 +17139,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMPVAR_CV_HAN GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_r_no_object: - zend_wrong_property_read(offset); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); } } while (0); +fetch_obj_r_finish: + zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -17254,7 +17181,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HA break; } } - goto fetch_obj_is_no_object; + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; } while (0); } @@ -17304,19 +17232,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMPVAR_CV_HA } } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_is_no_object: - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); } } while (0); +fetch_obj_is_finish: + zval_ptr_dtor_nogc(free_op1); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -17516,13 +17440,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C } else { zend_object *orig_obj = obj; - if (UNEXPECTED(obj->handlers->get_method == NULL)) { - zend_throw_error(NULL, "Object does not support method calls"); - - zval_ptr_dtor_nogc(free_op1); - HANDLE_EXCEPTION(); - } - if (IS_CV == IS_CONST) { function_name = EX_VAR(opline->op2.var); } @@ -17729,21 +17646,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TM if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } else { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } - if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { - zend_wrong_property_check(offset); -isset_no_object: - result = (opline->extended_value & ZEND_ISEMPTY); - } else { - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - } + + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + +isset_object_finish: zval_ptr_dtor_nogc(free_op1); ZEND_VM_SMART_BRANCH(result, 1); @@ -21909,8 +21825,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ assign_op_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -22335,8 +22250,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ pre_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -22412,8 +22326,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ post_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -22722,12 +22635,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { ZVAL_DEREF(value); } @@ -22843,12 +22750,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -22964,12 +22865,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -23085,12 +22980,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { ZVAL_DEREF(value); } @@ -24008,14 +23897,10 @@ num_index_dim: offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { - zend_use_object_as_array(); - } else { - if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - Z_OBJ_HT_P(container)->unset_dimension(container, offset); + if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; } + Z_OBJ_HT_P(container)->unset_dimension(container, offset); } else if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { zend_throw_error(NULL, "Cannot unset string offsets"); } @@ -24050,11 +23935,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDL break; } } - if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - } else { - zend_wrong_property_unset(offset); - } + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } while (0); if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; @@ -24274,8 +24155,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ assign_op_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -24702,8 +24582,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ pre_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -24780,8 +24659,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ post_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -25092,12 +24970,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { ZVAL_DEREF(value); } @@ -25213,12 +25085,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -25334,12 +25200,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -25455,12 +25315,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { ZVAL_DEREF(value); } @@ -26251,14 +26105,10 @@ num_index_dim: offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { - zend_use_object_as_array(); - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - Z_OBJ_HT_P(container)->unset_dimension(container, offset); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; } + Z_OBJ_HT_P(container)->unset_dimension(container, offset); } else if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { zend_throw_error(NULL, "Cannot unset string offsets"); } @@ -26294,11 +26144,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMPVAR_HAND break; } } - if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - } else { - zend_wrong_property_unset(offset); - } + Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } while (0); zval_ptr_dtor_nogc(free_op2); @@ -28172,8 +28018,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ assign_op_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -28598,8 +28443,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ pre_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -28675,8 +28519,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ post_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -28985,12 +28828,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { ZVAL_DEREF(value); } @@ -29106,12 +28943,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -29227,12 +29058,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -29348,12 +29173,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { ZVAL_DEREF(value); } @@ -30248,14 +30067,10 @@ num_index_dim: offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { - zend_use_object_as_array(); - } else { - if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - Z_OBJ_HT_P(container)->unset_dimension(container, offset); + if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; } + Z_OBJ_HT_P(container)->unset_dimension(container, offset); } else if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { zend_throw_error(NULL, "Cannot unset string offsets"); } @@ -30290,11 +30105,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER( break; } } - if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - } else { - zend_wrong_property_unset(offset); - } + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } while (0); if (UNEXPECTED(free_op1)) {zval_ptr_dtor_nogc(free_op1);}; @@ -30756,8 +30567,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ assign_op_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -30897,8 +30707,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ pre_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -30974,8 +30783,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ post_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -31048,7 +30856,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_U if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - goto fetch_obj_r_no_object; + zend_wrong_property_read(offset); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; } while (0); } @@ -31100,21 +30910,17 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_U GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_r_no_object: - zend_wrong_property_read(offset); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); } } while (0); +fetch_obj_r_finish: + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -31191,7 +30997,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST break; } } - goto fetch_obj_is_no_object; + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; } while (0); } @@ -31241,19 +31048,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST } } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_is_no_object: - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); } } while (0); +fetch_obj_is_finish: + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -31393,12 +31196,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { ZVAL_DEREF(value); } @@ -31514,12 +31311,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -31635,12 +31426,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -31756,12 +31541,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { ZVAL_DEREF(value); } @@ -31942,13 +31721,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S } else { zend_object *orig_obj = obj; - if (UNEXPECTED(obj->handlers->get_method == NULL)) { - zend_throw_error(NULL, "Object does not support method calls"); - - - HANDLE_EXCEPTION(); - } - if (IS_CONST == IS_CONST) { function_name = RT_CONSTANT(opline, opline->op2); } @@ -32255,11 +32027,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HA break; } } - if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - } else { - zend_wrong_property_unset(offset); - } + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } while (0); @@ -32288,21 +32056,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } else { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } - if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { - zend_wrong_property_check(offset); -isset_no_object: - result = (opline->extended_value & ZEND_ISEMPTY); - } else { - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - } + + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + +isset_object_finish: ZEND_VM_SMART_BRANCH(result, 1); @@ -32482,8 +32249,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ assign_op_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -32623,8 +32389,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ pre_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -32701,8 +32466,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ post_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -32776,7 +32540,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - goto fetch_obj_r_no_object; + zend_wrong_property_read(offset); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; } while (0); } @@ -32828,21 +32594,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMPVAR GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_r_no_object: - zend_wrong_property_read(offset); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); } } while (0); +fetch_obj_r_finish: zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -32920,7 +32681,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVA break; } } - goto fetch_obj_is_no_object; + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; } while (0); } @@ -32970,19 +32732,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMPVA } } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_is_no_object: - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); } } while (0); +fetch_obj_is_finish: zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -33123,12 +32880,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { ZVAL_DEREF(value); } @@ -33244,12 +32995,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -33365,12 +33110,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -33486,12 +33225,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { ZVAL_DEREF(value); } @@ -33673,13 +33406,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T } else { zend_object *orig_obj = obj; - if (UNEXPECTED(obj->handlers->get_method == NULL)) { - zend_throw_error(NULL, "Object does not support method calls"); - zval_ptr_dtor_nogc(free_op2); - - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); } @@ -33899,11 +33625,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMPVAR_H break; } } - if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - } else { - zend_wrong_property_unset(offset); - } + Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } while (0); zval_ptr_dtor_nogc(free_op2); @@ -33933,22 +33655,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } else { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } - if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { - zend_wrong_property_check(offset); -isset_no_object: - result = (opline->extended_value & ZEND_ISEMPTY); - } else { - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - } + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + +isset_object_finish: zval_ptr_dtor_nogc(free_op2); ZEND_VM_SMART_BRANCH(result, 1); @@ -34862,8 +34582,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ assign_op_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -35003,8 +34722,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ pre_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -35080,8 +34798,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ post_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -35154,7 +34871,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HAN if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - goto fetch_obj_r_no_object; + zend_wrong_property_read(offset); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; } while (0); } @@ -35206,21 +34925,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HAN GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_r_no_object: - zend_wrong_property_read(offset); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); } } while (0); +fetch_obj_r_finish: + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -35297,7 +35012,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HA break; } } - goto fetch_obj_is_no_object; + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; } while (0); } @@ -35347,19 +35063,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HA } } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_is_no_object: - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); } } while (0); +fetch_obj_is_finish: + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -35499,12 +35211,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { ZVAL_DEREF(value); } @@ -35620,12 +35326,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -35741,12 +35441,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -35862,12 +35556,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { ZVAL_DEREF(value); } @@ -36048,13 +35736,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C } else { zend_object *orig_obj = obj; - if (UNEXPECTED(obj->handlers->get_method == NULL)) { - zend_throw_error(NULL, "Object does not support method calls"); - - - HANDLE_EXCEPTION(); - } - if (IS_CV == IS_CONST) { function_name = EX_VAR(opline->op2.var); } @@ -36274,11 +35955,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDL break; } } - if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - } else { - zend_wrong_property_unset(offset); - } + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } while (0); @@ -36307,21 +35984,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UN if ((IS_UNUSED & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } else { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } - if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { - zend_wrong_property_check(offset); -isset_no_object: - result = (opline->extended_value & ZEND_ISEMPTY); - } else { - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - } + + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + +isset_object_finish: ZEND_VM_SMART_BRANCH(result, 1); @@ -38812,8 +38488,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ assign_op_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -39238,8 +38913,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ pre_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -39315,8 +38989,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ post_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -39631,7 +39304,9 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_C if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - goto fetch_obj_r_no_object; + zend_wrong_property_read(offset); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; } while (0); } @@ -39683,21 +39358,17 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_C GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_r_no_object: - zend_wrong_property_read(offset); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); } } while (0); +fetch_obj_r_finish: + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -39774,7 +39445,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HAN break; } } - goto fetch_obj_is_no_object; + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; } while (0); } @@ -39824,19 +39496,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HAN } } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_is_no_object: - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); } } while (0); +fetch_obj_is_finish: + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -39976,12 +39644,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { ZVAL_DEREF(value); } @@ -40097,12 +39759,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -40218,12 +39874,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -40339,12 +39989,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { ZVAL_DEREF(value); } @@ -41055,13 +40699,6 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S } else { zend_object *orig_obj = obj; - if (UNEXPECTED(obj->handlers->get_method == NULL)) { - zend_throw_error(NULL, "Object does not support method calls"); - - - HANDLE_EXCEPTION(); - } - if (IS_CONST == IS_CONST) { function_name = RT_CONSTANT(opline, opline->op2); } @@ -41363,14 +41000,10 @@ num_index_dim: offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { - zend_use_object_as_array(); - } else { - if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - Z_OBJ_HT_P(container)->unset_dimension(container, offset); + if (IS_CONST == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; } + Z_OBJ_HT_P(container)->unset_dimension(container, offset); } else if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { zend_throw_error(NULL, "Cannot unset string offsets"); } @@ -41405,11 +41038,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CONST_HANDLE break; } } - if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - } else { - zend_wrong_property_unset(offset); - } + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } while (0); @@ -41586,21 +41215,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } else { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } - if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { - zend_wrong_property_check(offset); -isset_no_object: - result = (opline->extended_value & ZEND_ISEMPTY); - } else { - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - } + + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + +isset_object_finish: ZEND_VM_SMART_BRANCH(result, 1); @@ -42701,8 +42329,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ assign_op_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -43129,8 +42756,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ pre_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -43207,8 +42833,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ post_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -43399,7 +43024,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HAN if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - goto fetch_obj_r_no_object; + zend_wrong_property_read(offset); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; } while (0); } @@ -43451,21 +43078,16 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMPVAR_HAN GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_r_no_object: - zend_wrong_property_read(offset); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); } } while (0); +fetch_obj_r_finish: zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -43543,7 +43165,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HA break; } } - goto fetch_obj_is_no_object; + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; } while (0); } @@ -43593,19 +43216,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMPVAR_HA } } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_is_no_object: - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); } } while (0); +fetch_obj_is_finish: zval_ptr_dtor_nogc(free_op2); ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); @@ -43746,12 +43364,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { ZVAL_DEREF(value); } @@ -43867,12 +43479,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -43988,12 +43594,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -44109,12 +43709,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { ZVAL_DEREF(value); } @@ -44769,13 +44363,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA } else { zend_object *orig_obj = obj; - if (UNEXPECTED(obj->handlers->get_method == NULL)) { - zend_throw_error(NULL, "Object does not support method calls"); - zval_ptr_dtor_nogc(free_op2); - - HANDLE_EXCEPTION(); - } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { function_name = _get_zval_ptr_var(opline->op2.var, &free_op2 EXECUTE_DATA_CC); } @@ -45023,14 +44610,10 @@ num_index_dim: offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { - zend_use_object_as_array(); - } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - Z_OBJ_HT_P(container)->unset_dimension(container, offset); + if ((IS_TMP_VAR|IS_VAR) == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; } + Z_OBJ_HT_P(container)->unset_dimension(container, offset); } else if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { zend_throw_error(NULL, "Cannot unset string offsets"); } @@ -45066,11 +44649,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMPVAR_HANDL break; } } - if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - } else { - zend_wrong_property_unset(offset); - } + Z_OBJ_HT_P(container)->unset_property(container, offset, (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } while (0); zval_ptr_dtor_nogc(free_op2); @@ -45172,22 +44751,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } else { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } - if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { - zend_wrong_property_check(offset); -isset_no_object: - result = (opline->extended_value & ZEND_ISEMPTY); - } else { - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - } + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + +isset_object_finish: zval_ptr_dtor_nogc(free_op2); ZEND_VM_SMART_BRANCH(result, 1); @@ -48450,8 +48027,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_binary_assign_op_obj_helper_SP /* here we are sure we are dealing with an object */ assign_op_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -48876,8 +48452,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_pre_incdec_property_helper_SPE /* here we are sure we are dealing with an object */ pre_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -48953,8 +48528,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_post_incdec_property_helper_SP /* here we are sure we are dealing with an object */ post_incdec_object: - if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) - && EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { + if (EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL))) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { @@ -49144,7 +48718,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) { GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - goto fetch_obj_r_no_object; + zend_wrong_property_read(offset); + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_r_finish; } while (0); } @@ -49196,21 +48772,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER GET_OP2_UNDEF_CV(offset, BP_VAR_R); } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_r_no_object: - zend_wrong_property_read(offset); - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { - retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); + retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var)); - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); - } else if (UNEXPECTED(Z_ISREF_P(retval))) { - zend_unwrap_reference(retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); + } else if (UNEXPECTED(Z_ISREF_P(retval))) { + zend_unwrap_reference(retval); } } while (0); +fetch_obj_r_finish: + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -49287,7 +48859,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLE break; } } - goto fetch_obj_is_no_object; + ZVAL_NULL(EX_VAR(opline->result.var)); + goto fetch_obj_is_finish; } while (0); } @@ -49337,19 +48910,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLE } } - if (UNEXPECTED(zobj->handlers->read_property == NULL)) { -fetch_obj_is_no_object: - ZVAL_NULL(EX_VAR(opline->result.var)); - } else { + retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var)); - - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); } } while (0); +fetch_obj_is_finish: + ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); } @@ -49489,12 +49058,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { ZVAL_DEREF(value); } @@ -49610,12 +49173,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -49731,12 +49288,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - zval_ptr_dtor_nogc(free_op_data); - goto exit_assign_obj; - } - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { ZVAL_DEREF(value); } @@ -49852,12 +49403,6 @@ fast_assign_obj: } } - if (!Z_OBJ_HT_P(object)->write_property) { - zend_wrong_property_assignment(property OPLINE_CC EXECUTE_DATA_CC); - - goto exit_assign_obj; - } - if (IS_CV == IS_CV || IS_CV == IS_VAR) { ZVAL_DEREF(value); } @@ -50616,13 +50161,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA } else { zend_object *orig_obj = obj; - if (UNEXPECTED(obj->handlers->get_method == NULL)) { - zend_throw_error(NULL, "Object does not support method calls"); - - - HANDLE_EXCEPTION(); - } - if (IS_CV == IS_CONST) { function_name = EX_VAR(opline->op2.var); } @@ -50870,14 +50408,10 @@ num_index_dim: offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R); } if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { - zend_use_object_as_array(); - } else { - if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { - offset++; - } - Z_OBJ_HT_P(container)->unset_dimension(container, offset); + if (IS_CV == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) { + offset++; } + Z_OBJ_HT_P(container)->unset_dimension(container, offset); } else if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { zend_throw_error(NULL, "Cannot unset string offsets"); } @@ -50912,11 +50446,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_CV_HANDLER(Z break; } } - if (Z_OBJ_HT_P(container)->unset_property) { - Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); - } else { - zend_wrong_property_unset(offset); - } + Z_OBJ_HT_P(container)->unset_property(container, offset, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL)); } while (0); @@ -51017,21 +50547,20 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV if ((IS_CV & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) { container = Z_REFVAL_P(container); if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } else { - goto isset_no_object; + result = (opline->extended_value & ZEND_ISEMPTY); + goto isset_object_finish; } } - if (UNEXPECTED(!Z_OBJ_HT_P(container)->has_property)) { - zend_wrong_property_check(offset); -isset_no_object: - result = (opline->extended_value & ZEND_ISEMPTY); - } else { - result = - (opline->extended_value & ZEND_ISEMPTY) ^ - Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); - } + + result = + (opline->extended_value & ZEND_ISEMPTY) ^ + Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISEMPTY), ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_ISEMPTY) : NULL)); + +isset_object_finish: ZEND_VM_SMART_BRANCH(result, 1); diff --git a/ext/com_dotnet/com_handlers.c b/ext/com_dotnet/com_handlers.c index 8424c3acfc0..13e31f945ab 100644 --- a/ext/com_dotnet/com_handlers.c +++ b/ext/com_dotnet/com_handlers.c @@ -562,7 +562,7 @@ zend_object_handlers php_com_object_handlers = { com_object_count, NULL, /* get_debug_info */ NULL, /* get_closure */ - NULL, /* get_gc */ + zend_std_get_gc, /* get_gc */ }; void php_com_object_enable_event_sink(php_com_dotnet_object *obj, int enable) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 8114625e683..59ff6526a75 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -4173,7 +4173,7 @@ ZEND_METHOD(reflection_class, hasProperty) } RETURN_TRUE; } else { - if (Z_TYPE(intern->obj) != IS_UNDEF && Z_OBJ_HANDLER(intern->obj, has_property)) { + if (Z_TYPE(intern->obj) != IS_UNDEF) { ZVAL_STR_COPY(&property, name); if (Z_OBJ_HANDLER(intern->obj, has_property)(&intern->obj, &property, 2, NULL)) { zval_ptr_dtor(&property); diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index f1688dbf16f..40fa9f3f064 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -897,10 +897,8 @@ static zend_function *spl_recursive_it_get_method(zend_object **zobject, zend_st function_handler = zend_std_get_method(zobject, method, key); if (!function_handler) { if ((function_handler = zend_hash_find_ptr(&Z_OBJCE_P(zobj)->function_table, method)) == NULL) { - if (Z_OBJ_HT_P(zobj)->get_method) { - *zobject = Z_OBJ_P(zobj); - function_handler = (*zobject)->handlers->get_method(zobject, method, key); - } + *zobject = Z_OBJ_P(zobj); + function_handler = (*zobject)->handlers->get_method(zobject, method, key); } else { *zobject = Z_OBJ_P(zobj); } diff --git a/ext/standard/array.c b/ext/standard/array.c index 4d94c54ff13..4e2916a7eb3 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -4097,10 +4097,6 @@ static inline zval *array_column_fetch_prop(zval *data, zval *name, zval *rv) /* zval *prop = NULL; if (Z_TYPE_P(data) == IS_OBJECT) { - if (!Z_OBJ_HANDLER_P(data, has_property) || !Z_OBJ_HANDLER_P(data, read_property)) { - return NULL; - } - /* The has_property check is first performed in "exists" mode (which returns true for * properties that are null but exist) and then in "has" mode to handle objects that * implement __isset (which is not called in "exists" mode). */ From 3412345ffefbefdee1da83350d3a45c4838e2b44 Mon Sep 17 00:00:00 2001 From: Peter Kokot Date: Tue, 16 Oct 2018 22:33:04 +0200 Subject: [PATCH 10/17] Remove unused variable makefile_am_files The `makefile_am_files` was part of the previous build system where automake was used to build Makefiles. Since 9d9d39a0de3bec962c343051011f5a2ed7d7b242 this is not used anymore and can be removed. --- build/build.mk | 1 - 1 file changed, 1 deletion(-) diff --git a/build/build.mk b/build/build.mk index 1ce958fa557..4fb49cd9ac6 100644 --- a/build/build.mk +++ b/build/build.mk @@ -29,7 +29,6 @@ all: $(STAMP) $(ALWAYS) @$(MAKE) -s -f build/build2.mk generated_lists: - @echo makefile_am_files = Zend/Makefile.am TSRM/Makefile.am > $@ @echo config_m4_files = Zend/Zend.m4 TSRM/tsrm.m4 TSRM/threads.m4 \ Zend/acinclude.m4 ext/*/config*.m4 sapi/*/config.m4 >> $@ From 9ef07c88bd76801e2d4fbfeab3ebfd6e6a67ac5f Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 17 Oct 2018 10:48:29 +0300 Subject: [PATCH 11/17] typo --- UPGRADING.INTERNALS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UPGRADING.INTERNALS b/UPGRADING.INTERNALS index dabb88c92de..85011cf4c4a 100644 --- a/UPGRADING.INTERNALS +++ b/UPGRADING.INTERNALS @@ -124,13 +124,13 @@ PHP 7.4 INTERNALS UPGRADE NOTES h. Opcache may make classes and op_arrays immutable. Such classes are marked by ZEND_ACC_IMMUTABLE flag, they are not going to be copied from opcache - shard memory to process memory and must not be modified at all. + shared memory to process memory and must not be modified at all. Few related data structures were changed to allow addressing mutable data structures from immutable ones. This access is implemented through ZEND_MAP_PTR... abstraction macros and, basically, uses additional level of indirection. op_array->run_time_cache, op_array->static_variables_ptr, class_entry->static_members_table and class_entry->iterator_funcs_ptr now - have to be access through ZEND_MAP_PTR... macros. + have to be accessed through ZEND_MAP_PTR... macros. It's also not allowed to change op_array->reserved[] handles of immutable op_arrays. Instead, now you have to reserve op_array handle using zend_get_op_array_extension_handle() during MINIT and access its value From 8dadca8864e66de70a24bdf1181bcf7dd8fb27d7 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 17 Oct 2018 11:05:43 +0300 Subject: [PATCH 12/17] Hide offset encoding magic in ZEND_MAP_PTR_IS_OFFSET(), ZEND_MAP_PTR_OFFSET2PTR() and ZEND_MAP_PTR_PTR2OFFSET() macros. --- Zend/zend.c | 2 +- Zend/zend_map_ptr.h | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Zend/zend.c b/Zend/zend.c index 5962a276b05..1e4d2a0f421 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -1676,7 +1676,7 @@ ZEND_API void *zend_map_ptr_new(void) #if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR return ptr; #elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET - return (void*)((CG(map_ptr_last) * sizeof(void*)) - (sizeof(void*) - 1)); + return ZEND_MAP_PTR_PTR2OFFSET(ptr); #else # error "Unknown ZEND_MAP_PTR_KIND" #endif diff --git a/Zend/zend_map_ptr.h b/Zend/zend_map_ptr.h index 0d5b8acd253..88872ab1fe5 100644 --- a/Zend/zend_map_ptr.h +++ b/Zend/zend_map_ptr.h @@ -51,13 +51,19 @@ ptr ## __ptr # define ZEND_MAP_PTR_DEF(type, name) \ type * ZEND_MAP_PTR(name) +# define ZEND_MAP_PTR_IS_OFFSET(ptr) \ + (((uintptr_t)ZEND_MAP_PTR(ptr)) & 1L) +# define ZEND_MAP_PTR_OFFSET2PTR(ptr) \ + ((void**)((char*)CG(map_ptr_base) + (uintptr_t)ZEND_MAP_PTR(ptr) - 1)) +# define ZEND_MAP_PTR_PTR2OFFSET(ptr) \ + ((void*)((uintptr_t)(((char*)(ptr)) - ((char*)CG(map_ptr_base))) | 1L)) # define ZEND_MAP_PTR_GET(ptr) \ - ((((uintptr_t)ZEND_MAP_PTR(ptr)) & 1L) ? \ - *(void**)((char*)CG(map_ptr_base) + (uintptr_t)ZEND_MAP_PTR(ptr) - 1) : \ + (ZEND_MAP_PTR_IS_OFFSET(ptr) ? \ + *(ZEND_MAP_PTR_OFFSET2PTR(ptr)) : \ (void*)(*(ZEND_MAP_PTR(ptr)))) # define ZEND_MAP_PTR_SET(ptr, val) do { \ - if (((uintptr_t)ZEND_MAP_PTR(ptr)) & 1L) { \ - *(void**)((char*)CG(map_ptr_base) + (uintptr_t)ZEND_MAP_PTR(ptr) - 1) = (val); \ + if (ZEND_MAP_PTR_IS_OFFSET(ptr)) { \ + *(ZEND_MAP_PTR_OFFSET2PTR(ptr)) = (val); \ } else { \ *(ZEND_MAP_PTR(ptr)) = (val); \ } \ From d5a41088401814c829847db212488f8aae39bcd2 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 17 Oct 2018 11:19:13 +0300 Subject: [PATCH 13/17] Removed duplicate code --- Zend/zend_execute.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 7ad16a9a781..6cf75d0926f 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -2507,16 +2507,6 @@ ZEND_API void zend_init_func_execute_data(zend_execute_data *ex, zend_op_array * ZEND_API void zend_init_code_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */ { EX(prev_execute_data) = EG(current_execute_data); - if (!ZEND_MAP_PTR(op_array->run_time_cache)) { - void *ptr; - - ZEND_ASSERT(op_array->fn_flags & ZEND_ACC_HEAP_RT_CACHE); - ptr = emalloc(op_array->cache_size + sizeof(void*)); - ZEND_MAP_PTR_INIT(op_array->run_time_cache, ptr); - ptr = (char*)ptr + sizeof(void*); - ZEND_MAP_PTR_SET(op_array->run_time_cache, ptr); - memset(ptr, 0, op_array->cache_size); - } i_init_code_execute_data(execute_data, op_array, return_value); } /* }}} */ From b945548e9306b1826c881918858b5e5aa3eb3002 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 17 Oct 2018 11:21:03 +0300 Subject: [PATCH 14/17] Removed redundand assertion --- Zend/zend_inheritance.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index a3eed785656..3468fb3a883 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -94,7 +94,7 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */ } if (ZEND_MAP_PTR(parent->iterator_funcs_ptr)) { /* Must be initialized through iface->interface_gets_implemented() */ - ZEND_ASSERT(ZEND_MAP_PTR(ce->iterator_funcs_ptr) && ZEND_MAP_PTR_GET(ce->iterator_funcs_ptr)); + ZEND_ASSERT(ZEND_MAP_PTR_GET(ce->iterator_funcs_ptr)); } if (EXPECTED(!ce->__get)) { ce->__get = parent->__get; From c63fc5d5f19c58498108d1698055b2b442227eb3 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 17 Oct 2018 11:36:51 +0300 Subject: [PATCH 15/17] Moved static class members initialization into the proper place. --- Zend/zend_inheritance.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index 3468fb3a883..afc01fc9ab7 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -885,6 +885,10 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent dst = end + parent_ce->default_static_members_count; ce->default_static_members_table = end; } + if (CE_STATIC_MEMBERS(parent_ce) == NULL) { + ZEND_ASSERT(parent_ce->type == ZEND_INTERNAL_CLASS || (parent_ce->ce_flags & ZEND_ACC_IMMUTABLE)); + zend_class_init_statics(parent_ce); + } if (UNEXPECTED(parent_ce->type != ce->type)) { /* User class extends internal */ if (UNEXPECTED(zend_update_class_constants(parent_ce) != SUCCESS)) { @@ -901,10 +905,6 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent } } while (dst != end); } else if (ce->type == ZEND_USER_CLASS) { - if (UNEXPECTED(CE_STATIC_MEMBERS(parent_ce) == NULL)) { - ZEND_ASSERT(parent_ce->type == ZEND_INTERNAL_CLASS || (parent_ce->ce_flags & ZEND_ACC_IMMUTABLE)); - zend_class_init_statics(parent_ce); - } src = CE_STATIC_MEMBERS(parent_ce) + parent_ce->default_static_members_count; do { dst--; From 0276ea51875bab37be01a4dc5e5a047c5698c571 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 17 Oct 2018 11:42:43 +0300 Subject: [PATCH 16/17] Added type cast --- Zend/zend_compile.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 034199f2e25..4a597dd4676 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -665,7 +665,7 @@ struct _zend_execute_data { ZEND_MAP_PTR_GET((op_array)->run_time_cache) #define ZEND_OP_ARRAY_EXTENSION(op_array, handle) \ - RUN_TIME_CACHE(op_array)[handle] + ((void**)RUN_TIME_CACHE(op_array))[handle] #if ZEND_EX_USE_RUN_TIME_CACHE From ad7a78b253be970db70c2251e66f9297d8e7f829 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 17 Oct 2018 11:46:30 +0300 Subject: [PATCH 17/17] Added comment --- Zend/zend_object_handlers.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 0cdd3242d70..48549dfb999 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1139,6 +1139,9 @@ ZEND_API zend_function *zend_get_call_trampoline_func(zend_class_entry *ce, zend size_t mname_len; zend_op_array *func; zend_function *fbc = is_static ? ce->__callstatic : ce->__call; + /* We use non-NULL value to avoid useless run_time_cache allocation. + * The low bit must be zero, to not be interpreted as a MAP_PTR offset. + */ static const void *dummy = (void*)(intptr_t)2; ZEND_ASSERT(fbc);