Merge branch 'immutable' into preload

* immutable:
  Added comment
  Added type cast
  Moved static class members initialization into the proper place.
  Removed redundand assertion
  Removed duplicate code
  Hide offset encoding magic in ZEND_MAP_PTR_IS_OFFSET(), ZEND_MAP_PTR_OFFSET2PTR() and ZEND_MAP_PTR_PTR2OFFSET() macros.
  typo
  Remove unused variable makefile_am_files
  Classify object handlers are required/optional
  Add support for getting SKIP_TAGSTART and SKIP_WHITE options
  Remove some obsolete config_vars.mk occurrences
  Remove bsd_converted from .gitignore
  Remove configuration parser and scanners ignores
  Remove obsolete buildconf.stamp from .gitignore
  [ci skip] Add magicdata.patch exception to .gitignore
  Remove outdated ext/spl/examples items from .gitignore
  Remove unused test.inc in ext/iconv/tests
This commit is contained in:
Dmitry Stogov 2018-10-17 12:29:59 +03:00
commit 21e0bebca3
32 changed files with 673 additions and 1282 deletions

10
.gitignore vendored
View file

@ -38,8 +38,6 @@ _libs
acconfig.h acconfig.h
aclocal.m4 aclocal.m4
autom4te.cache autom4te.cache
bsd_converted
buildconf.stamp
buildmk.stamp buildmk.stamp
confdefs.h confdefs.h
config.h config.h
@ -48,11 +46,6 @@ config.h.in
config.log config.log
config.nice config.nice
config.status config.status
config_vars.mk
configuration-parser.c
configuration-parser.h
configuration-parser.output
configuration-scanner.c
configure configure
conftest conftest
conftest.c conftest.c
@ -172,8 +165,6 @@ ext/phar/phar.phar
ext/phar/phar.1 ext/phar/phar.1
ext/phar/phar.phar.1 ext/phar/phar.phar.1
ext/phar/phar.php ext/phar/phar.php
ext/spl/examples/.htaccess
ext/spl/examples/*.phps
ext/sqlite3/tests/phpsql* ext/sqlite3/tests/phpsql*
# ------------------------------------------------------------------------------ Windows # ------------------------------------------------------------------------------ Windows
@ -205,5 +196,6 @@ ext/sqlite3/tests/phpsql*
# Special cases to invert previous ignore rules # Special cases to invert previous ignore rules
!ext/fileinfo/libmagic.patch !ext/fileinfo/libmagic.patch
!ext/fileinfo/magicdata.patch
!ext/mbstring/oniguruma.patch !ext/mbstring/oniguruma.patch
!ext/pcre/pcre2lib/config.h !ext/pcre/pcre2lib/config.h

View file

@ -7,7 +7,8 @@ PHP 7.4 INTERNALS UPGRADE NOTES
d. Removed zend_check_private() d. Removed zend_check_private()
e. php_win32_error_to_msg() memory management e. php_win32_error_to_msg() memory management
f. get_properties_for() handler / Z_OBJDEBUG_P f. get_properties_for() handler / Z_OBJDEBUG_P
g. Immutable classes and op_arrays g. Required object handlers
h. Immutable classes and op_arrays
2. Build system changes 2. Build system changes
a. Abstract a. Abstract
@ -99,15 +100,37 @@ PHP 7.4 INTERNALS UPGRADE NOTES
// ... // ...
zend_release_properties(ht); zend_release_properties(ht);
g. Opcache may make classes and op_arrays immutable. Such classes are marked 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.
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 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 Few related data structures were changed to allow addressing mutable data
structures from immutable ones. This access is implemented through structures from immutable ones. This access is implemented through
ZEND_MAP_PTR... abstraction macros and, basically, uses additional level of ZEND_MAP_PTR... abstraction macros and, basically, uses additional level of
indirection. op_array->run_time_cache, op_array->static_variables_ptr, indirection. op_array->run_time_cache, op_array->static_variables_ptr,
class_entry->static_members_table and class_entry->iterator_funcs_ptr now 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 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 op_arrays. Instead, now you have to reserve op_array handle using
zend_get_op_array_extension_handle() during MINIT and access its value zend_get_op_array_extension_handle() during MINIT and access its value

View file

@ -1676,7 +1676,7 @@ ZEND_API void *zend_map_ptr_new(void)
#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR #if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
return ptr; return ptr;
#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET #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 #else
# error "Unknown ZEND_MAP_PTR_KIND" # error "Unknown ZEND_MAP_PTR_KIND"
#endif #endif

View file

@ -3116,7 +3116,7 @@ get_function_via_handler:
fcc->function_handler = zend_get_call_trampoline_func(ce_org, mname, 0); fcc->function_handler = zend_get_call_trampoline_func(ce_org, mname, 0);
call_via_handler = 1; call_via_handler = 1;
retval = 1; retval = 1;
} else if (fcc->object->handlers->get_method) { } else {
fcc->function_handler = fcc->object->handlers->get_method(&fcc->object, mname, NULL); fcc->function_handler = fcc->object->handlers->get_method(&fcc->object, mname, NULL);
if (fcc->function_handler) { if (fcc->function_handler) {
if (strict_class && if (strict_class &&
@ -3933,9 +3933,6 @@ ZEND_API void zend_update_property_ex(zend_class_entry *scope, zval *object, zen
EG(fake_scope) = scope; 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); ZVAL_STR(&property, name);
Z_OBJ_HT_P(object)->write_property(object, &property, value, NULL); Z_OBJ_HT_P(object)->write_property(object, &property, value, NULL);
@ -3950,9 +3947,6 @@ ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const
EG(fake_scope) = scope; 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); ZVAL_STRINGL(&property, name, name_length);
Z_OBJ_HT_P(object)->write_property(object, &property, value, NULL); Z_OBJ_HT_P(object)->write_property(object, &property, value, NULL);
zval_ptr_dtor(&property); zval_ptr_dtor(&property);
@ -3977,9 +3971,6 @@ ZEND_API void zend_unset_property(zend_class_entry *scope, zval *object, const c
EG(fake_scope) = scope; 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); ZVAL_STRINGL(&property, name, name_length);
Z_OBJ_HT_P(object)->unset_property(object, &property, 0); Z_OBJ_HT_P(object)->unset_property(object, &property, 0);
zval_ptr_dtor(&property); zval_ptr_dtor(&property);
@ -4141,10 +4132,6 @@ ZEND_API zval *zend_read_property_ex(zend_class_entry *scope, zval *object, zend
EG(fake_scope) = scope; 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); ZVAL_STR(&property, name);
value = Z_OBJ_HT_P(object)->read_property(object, &property, silent?BP_VAR_IS:BP_VAR_R, NULL, rv); value = Z_OBJ_HT_P(object)->read_property(object, &property, silent?BP_VAR_IS:BP_VAR_R, NULL, rv);

View file

@ -1338,7 +1338,7 @@ ZEND_FUNCTION(method_exists)
if (zend_hash_exists(&ce->function_table, lcname)) { if (zend_hash_exists(&ce->function_table, lcname)) {
zend_string_release_ex(lcname, 0); zend_string_release_ex(lcname, 0);
RETURN_TRUE; 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_object *obj = Z_OBJ_P(klass);
zend_function *func = Z_OBJ_HT_P(klass)->get_method(&obj, method_name, NULL); zend_function *func = Z_OBJ_HT_P(klass)->get_method(&obj, method_name, NULL);
if (func != NULL) { if (func != NULL) {
@ -1401,7 +1401,6 @@ ZEND_FUNCTION(property_exists)
ZVAL_STR(&property_z, property); ZVAL_STR(&property_z, property);
if (Z_TYPE_P(object) == IS_OBJECT && 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)) { Z_OBJ_HANDLER_P(object, has_property)(object, &property_z, 2, NULL)) {
RETURN_TRUE; RETURN_TRUE;
} }

View file

@ -668,7 +668,7 @@ struct _zend_execute_data {
ZEND_MAP_PTR_GET((op_array)->run_time_cache) ZEND_MAP_PTR_GET((op_array)->run_time_cache)
#define ZEND_OP_ARRAY_EXTENSION(op_array, handle) \ #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 #if ZEND_EX_USE_RUN_TIME_CACHE

View file

@ -625,17 +625,6 @@ static zend_never_inline ZEND_COLD int zend_wrong_assign_to_variable_reference(z
return 1; 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 */ /* 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) 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) 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); Z_OBJ_HT_P(object)->write_dimension(object, dim, value);
if (UNEXPECTED(RETURN_VALUE_USED(opline))) { 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 *z;
zval rv, res; zval rv, res;
if (Z_OBJ_HT_P(object)->read_dimension && if ((z = Z_OBJ_HT_P(object)->read_dimension(object, property, BP_VAR_R, &rv)) != NULL) {
(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) { if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
zval rv2; 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); 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) 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", 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) 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 rv, obj; zval *z;
zval *z; zval z_copy;
zval z_copy;
ZVAL_OBJ(&obj, Z_OBJ_P(object)); ZVAL_OBJ(&obj, Z_OBJ_P(object));
Z_ADDREF(obj); Z_ADDREF(obj);
z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv); z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv);
if (UNEXPECTED(EG(exception))) { 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);
OBJ_RELEASE(Z_OBJ(obj)); OBJ_RELEASE(Z_OBJ(obj));
zval_ptr_dtor(&z_copy); ZVAL_UNDEF(EX_VAR(opline->result.var));
zval_ptr_dtor(z); return;
} else {
zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
ZVAL_NULL(EX_VAR(opline->result.var));
} }
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) 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 rv;
zval *z, obj;
zval z_copy;
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) { ZVAL_OBJ(&obj, Z_OBJ_P(object));
zval *z, obj; Z_ADDREF(obj);
zval z_copy; z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv);
if (UNEXPECTED(EG(exception))) {
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);
OBJ_RELEASE(Z_OBJ(obj)); 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))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var)); 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) 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)); ZVAL_OBJ(&obj, Z_OBJ_P(object));
Z_ADDREF(obj); 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);
z = Z_OBJ_HT(obj)->read_property(&obj, property, BP_VAR_R, cache_slot, &rv); if (UNEXPECTED(EG(exception))) {
if (UNEXPECTED(EG(exception))) { OBJ_RELEASE(Z_OBJ(obj));
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);
}
if (UNEXPECTED(RETURN_VALUE_USED(opline))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY(EX_VAR(opline->result.var), &res); ZVAL_UNDEF(EX_VAR(opline->result.var));
}
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));
} }
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)); 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"); 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) 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; zval *retval = NULL;
@ -1844,39 +1778,34 @@ fetch_from_array:
zval_undefined_cv(EX(opline)->op2.var EXECUTE_DATA_CC); zval_undefined_cv(EX(opline)->op2.var EXECUTE_DATA_CC);
dim = &EG(uninitialized_zval); dim = &EG(uninitialized_zval);
} }
if (!Z_OBJ_HT_P(container)->read_dimension) { if (dim_type == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
zend_use_object_as_array(); dim++;
ZVAL_ERROR(result); }
} else { 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))) { if (UNEXPECTED(retval == &EG(uninitialized_zval))) {
zend_class_entry *ce = Z_OBJCE_P(container); zend_class_entry *ce = Z_OBJCE_P(container);
ZVAL_NULL(result); ZVAL_NULL(result);
zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ZSTR_VAL(ce->name)); 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)) { } else if (EXPECTED(retval && Z_TYPE_P(retval) != IS_UNDEF)) {
if (!Z_ISREF_P(retval)) { 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);
}
if (result != retval) { if (result != retval) {
ZVAL_INDIRECT(result, retval); ZVAL_COPY(result, retval);
retval = result;
} }
} else { if (Z_TYPE_P(retval) != IS_OBJECT) {
ZVAL_ERROR(result); 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 { } else {
if (type != BP_VAR_W && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { 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); zval_undefined_cv(EX(opline)->op2.var EXECUTE_DATA_CC);
dim = &EG(uninitialized_zval); dim = &EG(uninitialized_zval);
} }
if (!Z_OBJ_HT_P(container)->read_dimension) { if (dim_type == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
zend_use_object_as_array(); dim++;
ZVAL_NULL(result); }
} else { 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); ZEND_ASSERT(result != NULL);
if (retval) { if (retval) {
if (result != retval) { if (result != retval) {
ZVAL_COPY_DEREF(result, retval); ZVAL_COPY_DEREF(result, retval);
} else if (UNEXPECTED(Z_ISREF_P(retval))) { } else if (UNEXPECTED(Z_ISREF_P(retval))) {
zend_unwrap_reference(result); zend_unwrap_reference(result);
}
} else {
ZVAL_NULL(result);
} }
} else {
ZVAL_NULL(result);
} }
} else { } else {
if (type != BP_VAR_IS && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) { 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 (/*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);
return Z_OBJ_HT_P(container)->has_dimension(container, offset, 0);
} else {
zend_use_object_as_array();
return 0;
}
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */ } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */
zend_long lval; 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 (/*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);
return !Z_OBJ_HT_P(container)->has_dimension(container, offset, 1);
} else {
zend_use_object_as_array();
return 1;
}
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */ } else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) { /* string offsets */
zend_long lval; 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) 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)) { if (container_op_type != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
do { do {
if (Z_ISREF_P(container)) { 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); ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, type, cache_slot);
if (NULL == ptr) { if (NULL == ptr) {
if (EXPECTED(Z_OBJ_HT_P(container)->read_property)) { ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result);
use_read_property: if (ptr != result) {
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 {
ZVAL_INDIRECT(result, ptr); 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 { } else {
zend_unsupported_property_reference(); ZVAL_INDIRECT(result, ptr);
ZVAL_ERROR(result);
} }
} }
@ -2604,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) /* {{{ */ 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); 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); i_init_code_execute_data(execute_data, op_array, return_value);
} }
/* }}} */ /* }}} */

View file

@ -617,17 +617,15 @@ tail_call:
GC_REF_SET_BLACK(ref); GC_REF_SET_BLACK(ref);
if (GC_TYPE(ref) == IS_OBJECT) { if (GC_TYPE(ref) == IS_OBJECT) {
zend_object_get_gc_t get_gc;
zend_object *obj = (zend_object*)ref; zend_object *obj = (zend_object*)ref;
if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED) && if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED))) {
(get_gc = obj->handlers->get_gc) != NULL)) {
int n; int n;
zval *zv, *end; zval *zv, *end;
zval tmp; zval tmp;
ZVAL_OBJ(&tmp, obj); ZVAL_OBJ(&tmp, obj);
ht = get_gc(&tmp, &zv, &n); ht = obj->handlers->get_gc(&tmp, &zv, &n);
end = zv + n; end = zv + n;
if (EXPECTED(!ht)) { if (EXPECTED(!ht)) {
if (!n) return; if (!n) return;
@ -727,17 +725,15 @@ tail_call:
GC_REF_SET_COLOR(ref, GC_GREY); GC_REF_SET_COLOR(ref, GC_GREY);
if (GC_TYPE(ref) == IS_OBJECT) { if (GC_TYPE(ref) == IS_OBJECT) {
zend_object_get_gc_t get_gc;
zend_object *obj = (zend_object*)ref; zend_object *obj = (zend_object*)ref;
if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED) && if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED))) {
(get_gc = obj->handlers->get_gc) != NULL)) {
int n; int n;
zval *zv, *end; zval *zv, *end;
zval tmp; zval tmp;
ZVAL_OBJ(&tmp, obj); ZVAL_OBJ(&tmp, obj);
ht = get_gc(&tmp, &zv, &n); ht = obj->handlers->get_gc(&tmp, &zv, &n);
end = zv + n; end = zv + n;
if (EXPECTED(!ht)) { if (EXPECTED(!ht)) {
if (!n) return; if (!n) return;
@ -883,17 +879,15 @@ tail_call:
} else { } else {
GC_REF_SET_COLOR(ref, GC_WHITE); GC_REF_SET_COLOR(ref, GC_WHITE);
if (GC_TYPE(ref) == IS_OBJECT) { if (GC_TYPE(ref) == IS_OBJECT) {
zend_object_get_gc_t get_gc;
zend_object *obj = (zend_object*)ref; zend_object *obj = (zend_object*)ref;
if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED) && if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED))) {
(get_gc = obj->handlers->get_gc) != NULL)) {
int n; int n;
zval *zv, *end; zval *zv, *end;
zval tmp; zval tmp;
ZVAL_OBJ(&tmp, obj); ZVAL_OBJ(&tmp, obj);
ht = get_gc(&tmp, &zv, &n); ht = obj->handlers->get_gc(&tmp, &zv, &n);
end = zv + n; end = zv + n;
if (EXPECTED(!ht)) { if (EXPECTED(!ht)) {
if (!n) return; if (!n) return;
@ -1023,11 +1017,9 @@ tail_call:
} }
if (GC_TYPE(ref) == IS_OBJECT) { if (GC_TYPE(ref) == IS_OBJECT) {
zend_object_get_gc_t get_gc;
zend_object *obj = (zend_object*)ref; zend_object *obj = (zend_object*)ref;
if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED) && if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED))) {
(get_gc = obj->handlers->get_gc) != NULL)) {
int n; int n;
zval *zv, *end; zval *zv, *end;
zval tmp; zval tmp;
@ -1036,13 +1028,12 @@ tail_call:
if (!GC_INFO(ref)) { if (!GC_INFO(ref)) {
gc_add_garbage(ref); gc_add_garbage(ref);
} }
if (obj->handlers->dtor_obj && if (obj->handlers->dtor_obj != zend_objects_destroy_object ||
((obj->handlers->dtor_obj != zend_objects_destroy_object) || obj->ce->destructor != NULL) {
(obj->ce->destructor != NULL))) {
*flags |= GC_HAS_DESTRUCTORS; *flags |= GC_HAS_DESTRUCTORS;
} }
ZVAL_OBJ(&tmp, obj); ZVAL_OBJ(&tmp, obj);
ht = get_gc(&tmp, &zv, &n); ht = obj->handlers->get_gc(&tmp, &zv, &n);
end = zv + n; end = zv + n;
if (EXPECTED(!ht)) { if (EXPECTED(!ht)) {
if (!n) return count; if (!n) return count;
@ -1193,17 +1184,15 @@ tail_call:
} }
if (GC_TYPE(ref) == IS_OBJECT) { if (GC_TYPE(ref) == IS_OBJECT) {
zend_object_get_gc_t get_gc;
zend_object *obj = (zend_object*)ref; zend_object *obj = (zend_object*)ref;
if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED) && if (EXPECTED(!(OBJ_FLAGS(ref) & IS_OBJ_FREE_CALLED))) {
(get_gc = obj->handlers->get_gc) != NULL)) {
int n; int n;
zval *zv, *end; zval *zv, *end;
zval tmp; zval tmp;
ZVAL_OBJ(&tmp, obj); ZVAL_OBJ(&tmp, obj);
ht = get_gc(&tmp, &zv, &n); ht = obj->handlers->get_gc(&tmp, &zv, &n);
end = zv + n; end = zv + n;
if (EXPECTED(!ht)) { if (EXPECTED(!ht)) {
if (!n) return; if (!n) return;
@ -1341,9 +1330,8 @@ ZEND_API int zend_gc_collect_cycles(void)
GC_TRACE_REF(obj, "calling destructor"); GC_TRACE_REF(obj, "calling destructor");
GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED); GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED);
if (obj->handlers->dtor_obj if (obj->handlers->dtor_obj != zend_objects_destroy_object
&& (obj->handlers->dtor_obj != zend_objects_destroy_object || obj->ce->destructor) {
|| obj->ce->destructor)) {
GC_ADDREF(obj); GC_ADDREF(obj);
obj->handlers->dtor_obj(obj); obj->handlers->dtor_obj(obj);
GC_DELREF(obj); GC_DELREF(obj);
@ -1392,11 +1380,9 @@ ZEND_API int zend_gc_collect_cycles(void)
(GC_TYPE_INFO(obj) & ~GC_TYPE_MASK); (GC_TYPE_INFO(obj) & ~GC_TYPE_MASK);
if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) { if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED); GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED);
if (obj->handlers->free_obj) { GC_ADDREF(obj);
GC_ADDREF(obj); obj->handlers->free_obj(obj);
obj->handlers->free_obj(obj); GC_DELREF(obj);
GC_DELREF(obj);
}
} }
ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(obj->handle); ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(obj->handle);

View file

@ -94,7 +94,7 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */
} }
if (ZEND_MAP_PTR(parent->iterator_funcs_ptr)) { if (ZEND_MAP_PTR(parent->iterator_funcs_ptr)) {
/* Must be initialized through iface->interface_gets_implemented() */ /* 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)) { if (EXPECTED(!ce->__get)) {
ce->__get = parent->__get; ce->__get = parent->__get;
@ -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; dst = end + parent_ce->default_static_members_count;
ce->default_static_members_table = end; 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)) { if (UNEXPECTED(parent_ce->type != ce->type)) {
/* User class extends internal */ /* User class extends internal */
if (UNEXPECTED(zend_update_class_constants(parent_ce) != SUCCESS)) { 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); } while (dst != end);
} else if (ce->type == ZEND_USER_CLASS) { } 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; src = CE_STATIC_MEMBERS(parent_ce) + parent_ce->default_static_members_count;
do { do {
dst--; dst--;

View file

@ -51,13 +51,19 @@
ptr ## __ptr ptr ## __ptr
# define ZEND_MAP_PTR_DEF(type, name) \ # define ZEND_MAP_PTR_DEF(type, name) \
type * ZEND_MAP_PTR(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) \ # define ZEND_MAP_PTR_GET(ptr) \
((((uintptr_t)ZEND_MAP_PTR(ptr)) & 1L) ? \ (ZEND_MAP_PTR_IS_OFFSET(ptr) ? \
*(void**)((char*)CG(map_ptr_base) + (uintptr_t)ZEND_MAP_PTR(ptr) - 1) : \ *(ZEND_MAP_PTR_OFFSET2PTR(ptr)) : \
(void*)(*(ZEND_MAP_PTR(ptr)))) (void*)(*(ZEND_MAP_PTR(ptr))))
# define ZEND_MAP_PTR_SET(ptr, val) do { \ # define ZEND_MAP_PTR_SET(ptr, val) do { \
if (((uintptr_t)ZEND_MAP_PTR(ptr)) & 1L) { \ if (ZEND_MAP_PTR_IS_OFFSET(ptr)) { \
*(void**)((char*)CG(map_ptr_base) + (uintptr_t)ZEND_MAP_PTR(ptr) - 1) = (val); \ *(ZEND_MAP_PTR_OFFSET2PTR(ptr)) = (val); \
} else { \ } else { \
*(ZEND_MAP_PTR(ptr)) = (val); \ *(ZEND_MAP_PTR(ptr)) = (val); \
} \ } \

View file

@ -1139,6 +1139,9 @@ ZEND_API zend_function *zend_get_call_trampoline_func(zend_class_entry *ce, zend
size_t mname_len; size_t mname_len;
zend_op_array *func; zend_op_array *func;
zend_function *fbc = is_static ? ce->__callstatic : ce->__call; 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; static const void *dummy = (void*)(intptr_t)2;
ZEND_ASSERT(fbc); ZEND_ASSERT(fbc);

View file

@ -153,36 +153,35 @@ typedef int (*zend_object_do_operation_t)(zend_uchar opcode, zval *result, zval
struct _zend_object_handlers { struct _zend_object_handlers {
/* offset of real object header (usually zero) */ /* offset of real object header (usually zero) */
int offset; int offset;
/* general object functions */ /* object handlers */
zend_object_free_obj_t free_obj; zend_object_free_obj_t free_obj; /* required */
zend_object_dtor_obj_t dtor_obj; zend_object_dtor_obj_t dtor_obj; /* required */
zend_object_clone_obj_t clone_obj; zend_object_clone_obj_t clone_obj; /* optional */
/* individual object functions */ zend_object_read_property_t read_property; /* required */
zend_object_read_property_t read_property; zend_object_write_property_t write_property; /* required */
zend_object_write_property_t write_property; zend_object_read_dimension_t read_dimension; /* required */
zend_object_read_dimension_t read_dimension; zend_object_write_dimension_t write_dimension; /* required */
zend_object_write_dimension_t write_dimension; zend_object_get_property_ptr_ptr_t get_property_ptr_ptr; /* required */
zend_object_get_property_ptr_ptr_t get_property_ptr_ptr; zend_object_get_t get; /* optional */
zend_object_get_t get; zend_object_set_t set; /* optional */
zend_object_set_t set; zend_object_has_property_t has_property; /* required */
zend_object_has_property_t has_property; zend_object_unset_property_t unset_property; /* required */
zend_object_unset_property_t unset_property; zend_object_has_dimension_t has_dimension; /* required */
zend_object_has_dimension_t has_dimension; zend_object_unset_dimension_t unset_dimension; /* required */
zend_object_unset_dimension_t unset_dimension; zend_object_get_properties_t get_properties; /* required */
zend_object_get_properties_t get_properties; /* required */ zend_object_get_method_t get_method; /* required */
zend_object_get_method_t get_method; zend_object_call_method_t call_method; /* optional */
zend_object_call_method_t call_method; zend_object_get_constructor_t get_constructor; /* required */
zend_object_get_constructor_t get_constructor; zend_object_get_class_name_t get_class_name; /* required */
zend_object_get_class_name_t get_class_name; zend_object_compare_t compare_objects; /* optional */
zend_object_compare_t compare_objects; zend_object_cast_t cast_object; /* optional */
zend_object_cast_t cast_object; zend_object_count_elements_t count_elements; /* optional */
zend_object_count_elements_t count_elements; zend_object_get_debug_info_t get_debug_info; /* optional */
zend_object_get_debug_info_t get_debug_info; zend_object_get_closure_t get_closure; /* optional */
zend_object_get_closure_t get_closure; zend_object_get_gc_t get_gc; /* required */
zend_object_get_gc_t get_gc; zend_object_do_operation_t do_operation; /* optional */
zend_object_do_operation_t do_operation; zend_object_compare_zvals_t compare; /* optional */
zend_object_compare_zvals_t compare; zend_object_get_properties_for_t get_properties_for; /* optional */
zend_object_get_properties_for_t get_properties_for; /* optional */
}; };
BEGIN_EXTERN_C() BEGIN_EXTERN_C()

View file

@ -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)) { if (!(OBJ_FLAGS(obj) & IS_OBJ_DESTRUCTOR_CALLED)) {
GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED); GC_ADD_FLAGS(obj, IS_OBJ_DESTRUCTOR_CALLED);
if (obj->handlers->dtor_obj if (obj->handlers->dtor_obj != zend_objects_destroy_object
&& (obj->handlers->dtor_obj != zend_objects_destroy_object || obj->ce->destructor) {
|| obj->ce->destructor)) {
GC_ADDREF(obj); GC_ADDREF(obj);
obj->handlers->dtor_obj(obj); obj->handlers->dtor_obj(obj);
GC_DELREF(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 (IS_OBJ_VALID(obj)) {
if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) { if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
GC_ADD_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); GC_ADDREF(obj);
obj->handlers->free_obj(obj); obj->handlers->free_obj(obj);
GC_DELREF(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 (IS_OBJ_VALID(obj)) {
if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) { if (!(OBJ_FLAGS(obj) & IS_OBJ_FREE_CALLED)) {
GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED); GC_ADD_FLAGS(obj, IS_OBJ_FREE_CALLED);
if (obj->handlers->free_obj) { GC_ADDREF(obj);
GC_ADDREF(obj); obj->handlers->free_obj(obj);
obj->handlers->free_obj(obj); GC_DELREF(obj);
GC_DELREF(obj);
}
} }
} }
} while (obj_ptr != end); } 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)) { if (!(OBJ_FLAGS(object) & IS_OBJ_DESTRUCTOR_CALLED)) {
GC_ADD_FLAGS(object, IS_OBJ_DESTRUCTOR_CALLED); GC_ADD_FLAGS(object, IS_OBJ_DESTRUCTOR_CALLED);
if (object->handlers->dtor_obj if (object->handlers->dtor_obj != zend_objects_destroy_object
&& (object->handlers->dtor_obj != zend_objects_destroy_object || object->ce->destructor) {
|| object->ce->destructor)) {
GC_ADDREF(object); GC_ADDREF(object);
object->handlers->dtor_obj(object); object->handlers->dtor_obj(object);
GC_DELREF(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); EG(objects_store).object_buckets[handle] = SET_OBJ_INVALID(object);
if (!(OBJ_FLAGS(object) & IS_OBJ_FREE_CALLED)) { if (!(OBJ_FLAGS(object) & IS_OBJ_FREE_CALLED)) {
GC_ADD_FLAGS(object, IS_OBJ_FREE_CALLED); GC_ADD_FLAGS(object, IS_OBJ_FREE_CALLED);
if (object->handlers->free_obj) { GC_ADDREF(object);
GC_ADDREF(object); object->handlers->free_obj(object);
object->handlers->free_obj(object); GC_DELREF(object);
GC_DELREF(object);
}
} }
ptr = ((char*)object) - object->handlers->offset; ptr = ((char*)object) - object->handlers->offset;
GC_REMOVE_FROM_BUFFER(object); GC_REMOVE_FROM_BUFFER(object);

View file

@ -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 */ /* here we are sure we are dealing with an object */
ZEND_VM_C_LABEL(assign_op_object): ZEND_VM_C_LABEL(assign_op_object):
if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) 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)) {
&& 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(Z_ISERROR_P(zptr))) {
if (UNEXPECTED(RETURN_VALUE_USED(opline))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var)); 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 */ /* here we are sure we are dealing with an object */
ZEND_VM_C_LABEL(pre_incdec_object): ZEND_VM_C_LABEL(pre_incdec_object):
if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) 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)) {
&& 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(Z_ISERROR_P(zptr))) {
if (UNEXPECTED(RETURN_VALUE_USED(opline))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var)); 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 */ /* here we are sure we are dealing with an object */
ZEND_VM_C_LABEL(post_incdec_object): ZEND_VM_C_LABEL(post_incdec_object):
if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr) 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)) {
&& 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(Z_ISERROR_P(zptr))) {
ZVAL_NULL(EX_VAR(opline->result.var)); ZVAL_NULL(EX_VAR(opline->result.var));
} else { } 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)) { if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(offset) == IS_UNDEF)) {
GET_OP2_UNDEF_CV(offset, BP_VAR_R); 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); } 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); GET_OP2_UNDEF_CV(offset, BP_VAR_R);
} }
if (UNEXPECTED(zobj->handlers->read_property == NULL)) { retval = zobj->handlers->read_property(container, offset, BP_VAR_R, cache_slot, EX_VAR(opline->result.var));
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));
if (retval != EX_VAR(opline->result.var)) { if (retval != EX_VAR(opline->result.var)) {
ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval); ZVAL_COPY_DEREF(EX_VAR(opline->result.var), retval);
} else if (UNEXPECTED(Z_ISREF_P(retval))) { } else if (UNEXPECTED(Z_ISREF_P(retval))) {
zend_unwrap_reference(retval); zend_unwrap_reference(retval);
}
} }
} while (0); } while (0);
ZEND_VM_C_LABEL(fetch_obj_r_finish):
FREE_OP2(); FREE_OP2();
FREE_OP1(); FREE_OP1();
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); 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; 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); } 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)) { retval = zobj->handlers->read_property(container, offset, BP_VAR_IS, cache_slot, EX_VAR(opline->result.var));
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)); 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); } while (0);
ZEND_VM_C_LABEL(fetch_obj_is_finish):
FREE_OP2(); FREE_OP2();
FREE_OP1(); FREE_OP1();
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION(); 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) { if (OP_DATA_TYPE == IS_CV || OP_DATA_TYPE == IS_VAR) {
ZVAL_DEREF(value); ZVAL_DEREF(value);
} }
@ -3072,13 +3056,6 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV,
} else { } else {
zend_object *orig_obj = obj; 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) { if (OP2_TYPE == IS_CONST) {
function_name = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); 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); offset = GET_OP2_UNDEF_CV(offset, BP_VAR_R);
} }
if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { if (OP2_TYPE == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
zend_use_object_as_array(); offset++;
} else {
if (OP2_TYPE == IS_CONST && Z_EXTRA_P(offset) == ZEND_EXTRA_VALUE) {
offset++;
}
Z_OBJ_HT_P(container)->unset_dimension(container, offset);
} }
Z_OBJ_HT_P(container)->unset_dimension(container, offset);
} else if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) { } else if (OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
zend_throw_error(NULL, "Cannot unset string offsets"); 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; 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));
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);
}
} while (0); } while (0);
FREE_OP2(); 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)) { if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container); container = Z_REFVAL_P(container);
if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { 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 { } 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_OP2();
FREE_OP1(); FREE_OP1();
ZEND_VM_SMART_BRANCH(result, 1); ZEND_VM_SMART_BRANCH(result, 1);

File diff suppressed because it is too large Load diff

View file

@ -29,7 +29,6 @@ all: $(STAMP) $(ALWAYS)
@$(MAKE) -s -f build/build2.mk @$(MAKE) -s -f build/build2.mk
generated_lists: 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 \ @echo config_m4_files = Zend/Zend.m4 TSRM/tsrm.m4 TSRM/threads.m4 \
Zend/acinclude.m4 ext/*/config*.m4 sapi/*/config.m4 >> $@ Zend/acinclude.m4 ext/*/config*.m4 sapi/*/config.m4 >> $@

View file

@ -562,7 +562,7 @@ zend_object_handlers php_com_object_handlers = {
com_object_count, com_object_count,
NULL, /* get_debug_info */ NULL, /* get_debug_info */
NULL, /* get_closure */ 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) void php_com_object_enable_event_sink(php_com_dotnet_object *obj, int enable)

View file

@ -6,7 +6,6 @@ EUC-JP to ISO-2022-JP
error_reporting=2039 error_reporting=2039
--FILE-- --FILE--
<?php <?php
/* include('test.inc'); */
/* charset=EUC-JP */ /* charset=EUC-JP */
function hexdump($str) { function hexdump($str) {

View file

@ -6,7 +6,6 @@ EUC-JP to SJIS
error_reporting=2039 error_reporting=2039
--FILE-- --FILE--
<?php <?php
/* include('test.inc'); */
/* charset=EUC-JP */ /* charset=EUC-JP */
$str = " $str = "

View file

@ -6,7 +6,6 @@ EUC-JP to UTF8
error_reporting=2039 error_reporting=2039
--FILE-- --FILE--
<?php <?php
/* include('test.inc'); */
/* charset=EUC-JP */ /* charset=EUC-JP */
$str = " $str = "

View file

@ -6,7 +6,6 @@ iconv() test 1
error_reporting=2039 error_reporting=2039
--FILE-- --FILE--
<?php <?php
/* include('test.inc'); */
echo "iconv extension is available\n"; echo "iconv extension is available\n";
$test = "æøå"; $test = "æøå";
var_dump("ISO-8859-1: $test"); var_dump("ISO-8859-1: $test");

View file

@ -11,7 +11,6 @@ if (@iconv("ascii","UCS-4LE", "abcd") == '') {
error_reporting=2039 error_reporting=2039
--FILE-- --FILE--
<?php <?php
/* include('test.inc'); */
/* /*
Expected output: Expected output:
&#97;&#98;&#99;&#100; &#97;&#98;&#99;&#100;

View file

@ -6,7 +6,6 @@ ob_iconv_handler()
error_reporting=2039 error_reporting=2039
--FILE-- --FILE--
<?php <?php
/* include('test.inc'); */
iconv_set_encoding('internal_encoding', 'EUC-JP'); iconv_set_encoding('internal_encoding', 'EUC-JP');
iconv_set_encoding('output_encoding', 'Shift_JIS'); iconv_set_encoding('output_encoding', 'Shift_JIS');
ob_start('ob_iconv_handler'); ob_start('ob_iconv_handler');

View file

@ -1,7 +0,0 @@
<?php
// Do not dl load extension
//if (!extension_loaded("iconv") && ini_get("enable_dl")) {
// $dlext = (substr(PHP_OS, 0, 3) == "WIN") ? ".dll" : ".so";
// @dl("iconv$dlext");
//}
?>

View file

@ -9,7 +9,6 @@ include('skipif.inc');
error_reporting=2039 error_reporting=2039
--FILE-- --FILE--
<?php <?php
/* include('test.inc'); */
// Should be ok. // Should be ok.
// Content from file is from libiconv testkit. Tested both // Content from file is from libiconv testkit. Tested both
// with a string as an implode, no difference. // with a string as an implode, no difference.

View file

@ -9,7 +9,6 @@ include('skipif.inc');
error_reporting=2047 error_reporting=2047
--FILE-- --FILE--
<?php // vim600: syn=php <?php // vim600: syn=php
/* include('test.inc'); */
//error_reporting(E_ALL); //error_reporting(E_ALL);
$utf = implode('', file(dirname(__FILE__).'/Quotes.UTF-8')); $utf = implode('', file(dirname(__FILE__).'/Quotes.UTF-8'));

View file

@ -4175,7 +4175,7 @@ ZEND_METHOD(reflection_class, hasProperty)
} }
RETURN_TRUE; RETURN_TRUE;
} else { } 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); ZVAL_STR_COPY(&property, name);
if (Z_OBJ_HANDLER(intern->obj, has_property)(&intern->obj, &property, 2, NULL)) { if (Z_OBJ_HANDLER(intern->obj, has_property)(&intern->obj, &property, 2, NULL)) {
zval_ptr_dtor(&property); zval_ptr_dtor(&property);

View file

@ -899,10 +899,8 @@ static zend_function *spl_recursive_it_get_method(zend_object **zobject, zend_st
function_handler = zend_std_get_method(zobject, method, key); function_handler = zend_std_get_method(zobject, method, key);
if (!function_handler) { if (!function_handler) {
if ((function_handler = zend_hash_find_ptr(&Z_OBJCE_P(zobj)->function_table, method)) == NULL) { 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);
*zobject = Z_OBJ_P(zobj); function_handler = (*zobject)->handlers->get_method(zobject, method, key);
function_handler = (*zobject)->handlers->get_method(zobject, method, key);
}
} else { } else {
*zobject = Z_OBJ_P(zobj); *zobject = Z_OBJ_P(zobj);
} }

View file

@ -4097,10 +4097,6 @@ static inline zval *array_column_fetch_prop(zval *data, zval *name, zval *rv) /*
zval *prop = NULL; zval *prop = NULL;
if (Z_TYPE_P(data) == IS_OBJECT) { 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 /* 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 * properties that are null but exist) and then in "has" mode to handle objects that
* implement __isset (which is not called in "exists" mode). */ * implement __isset (which is not called in "exists" mode). */

View file

@ -0,0 +1,29 @@
--TEST--
xml_parser_get_option() with XML_OPTION_SKIP_TAGSTART and XML_OPTION_SKIP_WHITE
--SKIPIF--
<?php
if (!extension_loaded('xml')) die('skip xml extension not available');
?>
--FILE--
<?php
$parser = xml_parser_create();
echo "defaults:\n";
var_dump(xml_parser_get_option($parser, XML_OPTION_SKIP_TAGSTART));
var_dump(xml_parser_get_option($parser, XML_OPTION_SKIP_WHITE));
echo "setting:\n";
var_dump(xml_parser_set_option($parser, XML_OPTION_SKIP_TAGSTART, 7));
var_dump(xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1));
echo "getting:\n";
var_dump(xml_parser_get_option($parser, XML_OPTION_SKIP_TAGSTART));
var_dump(xml_parser_get_option($parser, XML_OPTION_SKIP_WHITE));
?>
--EXPECT--
defaults:
int(0)
int(0)
setting:
bool(true)
bool(true)
getting:
int(7)
int(1)

View file

@ -1662,6 +1662,12 @@ PHP_FUNCTION(xml_parser_get_option)
case PHP_XML_OPTION_CASE_FOLDING: case PHP_XML_OPTION_CASE_FOLDING:
RETURN_LONG(parser->case_folding); RETURN_LONG(parser->case_folding);
break; 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: case PHP_XML_OPTION_TARGET_ENCODING:
RETURN_STRING((char *)parser->target_encoding); RETURN_STRING((char *)parser->target_encoding);
break; break;

View file

@ -13,7 +13,7 @@ if test ! -f Makefile.in || test ! -f config.m4; then
fi fi
rm -rf modules *.lo *.o *.la config.status config.cache \ 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\`` myname=`basename \`pwd\``
cd .. cd ..