Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Zend/zend_exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,7 @@ ZEND_API ZEND_COLD void zend_exception_error(zend_object *ex, int severity) /* {
zend_string *str, *file = NULL;
zend_long line = 0;

zend_call_method_with_0_params(Z_OBJ(exception), ce_exception, &ex->ce->__tostring, "__tostring", &tmp);
zend_call_method_with_0_params_ex(Z_OBJ(exception), ce_exception, &ex->ce->__tostring, ZSTR_KNOWN(ZEND_STR_MAGIC_TO_STRING), &tmp);
if (!EG(exception)) {
if (Z_TYPE(tmp) != IS_STRING) {
zend_error(E_WARNING, "%s::__toString() must return a string", ZSTR_VAL(ce_exception->name));
Expand All @@ -941,7 +941,7 @@ ZEND_API ZEND_COLD void zend_exception_error(zend_object *ex, int severity) /* {
}

zend_error_va(E_WARNING, (file && ZSTR_LEN(file) > 0) ? ZSTR_VAL(file) : NULL, line,
"Uncaught %s in exception handling during call to %s::__tostring()",
"Uncaught %s in exception handling during call to %s::__toString()",
ZSTR_VAL(Z_OBJCE(zv)->name), ZSTR_VAL(ce_exception->name));

if (file) {
Expand Down
67 changes: 44 additions & 23 deletions Zend/zend_interfaces.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,24 @@ ZEND_API zend_class_entry *zend_ce_stringable;
/* {{{ zend_call_method
Only returns the returned zval if retval_ptr != NULL */
ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, zend_function **fn_proxy, const char *function_name, size_t function_name_len, zval *retval_ptr, int param_count, zval* arg1, zval* arg2)
{
zend_string *function_name_str = NULL;
zval *retval;

if (!fn_proxy || !*fn_proxy) {
function_name_str = zend_string_init(function_name, function_name_len, 0);
}
retval = zend_call_method_ex(object, obj_ce, fn_proxy, function_name_str, retval_ptr, param_count, arg1, arg2);
if (function_name_str) {
zend_string_efree(function_name_str);
}

return retval;
}
/* }}} */

/* {{{ zend_call_method_ex */
ZEND_API zval* zend_call_method_ex(zend_object *object, zend_class_entry *obj_ce, zend_function **fn_proxy, zend_string *function_name, zval *retval_ptr, int param_count, zval* arg1, zval* arg2)
{
int result;
zend_fcall_info fci;
Expand All @@ -53,12 +71,13 @@ ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, z
fci.params = params;
fci.no_separation = 1;

ZEND_ASSERT(function_name || (fn_proxy && *fn_proxy));

if (!fn_proxy && !obj_ce) {
/* no interest in caching and no information already present that is
* needed later inside zend_call_function. */
ZVAL_STRINGL(&fci.function_name, function_name, function_name_len);
ZVAL_STR(&fci.function_name, function_name);
result = zend_call_function(&fci, NULL);
zval_ptr_dtor(&fci.function_name);
} else {
zend_fcall_info_cache fcic;
ZVAL_UNDEF(&fci.function_name); /* Unused */
Expand All @@ -68,17 +87,16 @@ ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, z
}
if (!fn_proxy || !*fn_proxy) {
if (EXPECTED(obj_ce)) {
fcic.function_handler = zend_hash_str_find_ptr(
&obj_ce->function_table, function_name, function_name_len);
fcic.function_handler = zend_hash_find_ptr(&obj_ce->function_table, function_name);
if (UNEXPECTED(fcic.function_handler == NULL)) {
/* error at c-level */
zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for method %s::%s", ZSTR_VAL(obj_ce->name), function_name);
zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for method %s::%s", ZSTR_VAL(obj_ce->name), ZSTR_VAL(function_name));
}
} else {
fcic.function_handler = zend_fetch_function_str(function_name, function_name_len);
fcic.function_handler = zend_fetch_function(function_name);
if (UNEXPECTED(fcic.function_handler == NULL)) {
/* error at c-level */
zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for function %s", function_name);
zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for function %s", ZSTR_VAL(function_name));
}
}
if (fn_proxy) {
Expand All @@ -94,8 +112,8 @@ ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, z
zend_class_entry *called_scope = zend_get_called_scope(EG(current_execute_data));

if (obj_ce &&
(!called_scope ||
!instanceof_function(called_scope, obj_ce))) {
(!called_scope ||
!instanceof_function(called_scope, obj_ce))) {
fcic.called_scope = obj_ce;
} else {
fcic.called_scope = called_scope;
Expand All @@ -104,13 +122,16 @@ ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, z
fcic.object = object;
result = zend_call_function(&fci, &fcic);
}
if (result == FAILURE) {
if (UNEXPECTED(result == FAILURE)) {
/* error at c-level */
if (!obj_ce) {
obj_ce = object ? object->ce : NULL;
}
if (!EG(exception)) {
zend_error_noreturn(E_CORE_ERROR, "Couldn't execute method %s%s%s", obj_ce ? ZSTR_VAL(obj_ce->name) : "", obj_ce ? "::" : "", function_name);
if (UNEXPECTED(!EG(exception))) {
if (!obj_ce) {
obj_ce = object ? object->ce : NULL;
}
if (!function_name) {
function_name = (*fn_proxy)->common.function_name;
}
zend_error_noreturn(E_CORE_ERROR, "Couldn't execute method %s%s%s", obj_ce ? ZSTR_VAL(obj_ce->name) : "", obj_ce ? "::" : "", ZSTR_VAL(function_name));
}
}
if (!retval_ptr) {
Expand All @@ -126,7 +147,7 @@ ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, z
/* {{{ zend_user_it_new_iterator */
ZEND_API void zend_user_it_new_iterator(zend_class_entry *ce, zval *object, zval *retval)
{
zend_call_method_with_0_params(Z_OBJ_P(object), ce, &ce->iterator_funcs_ptr->zf_new_iterator, "getiterator", retval);
zend_call_method_with_0_params_ex(Z_OBJ_P(object), ce, &ce->iterator_funcs_ptr->zf_new_iterator, ZSTR_KNOWN(ZEND_STR_GET_ITERATOR), retval);
}
/* }}} */

Expand Down Expand Up @@ -162,7 +183,7 @@ ZEND_API int zend_user_it_valid(zend_object_iterator *_iter)
zval more;
int result;

zend_call_method_with_0_params(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_valid, "valid", &more);
zend_call_method_with_0_params_ex(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_valid, ZSTR_KNOWN(ZEND_STR_VALID), &more);
result = i_zend_is_true(&more);
zval_ptr_dtor(&more);
return result ? SUCCESS : FAILURE;
Expand All @@ -178,7 +199,7 @@ ZEND_API zval *zend_user_it_get_current_data(zend_object_iterator *_iter)
zval *object = &iter->it.data;

if (Z_ISUNDEF(iter->value)) {
zend_call_method_with_0_params(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_current, "current", &iter->value);
zend_call_method_with_0_params_ex(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_current, ZSTR_KNOWN(ZEND_STR_CURRENT), &iter->value);
}
return &iter->value;
}
Expand All @@ -191,7 +212,7 @@ ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *ke
zval *object = &iter->it.data;
zval retval;

zend_call_method_with_0_params(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_key, "key", &retval);
zend_call_method_with_0_params_ex(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_key, ZSTR_KNOWN(ZEND_STR_KEY), &retval);

if (Z_TYPE(retval) != IS_UNDEF) {
ZVAL_COPY_VALUE(key, &retval);
Expand All @@ -212,7 +233,7 @@ ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter)
zval *object = &iter->it.data;

zend_user_it_invalidate_current(_iter);
zend_call_method_with_0_params(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_next, "next", NULL);
zend_call_method_with_0_params_ex(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_next, ZSTR_KNOWN(ZEND_STR_NEXT), NULL);
}
/* }}} */

Expand All @@ -223,7 +244,7 @@ ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter)
zval *object = &iter->it.data;

zend_user_it_invalidate_current(_iter);
zend_call_method_with_0_params(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_rewind, "rewind", NULL);
zend_call_method_with_0_params_ex(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_rewind, ZSTR_KNOWN(ZEND_STR_REWIND), NULL);
}
/* }}} */

Expand Down Expand Up @@ -398,7 +419,7 @@ ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, size_t *b
zval retval;
int result;

zend_call_method_with_0_params(Z_OBJ_P(object), ce, &ce->serialize_func, "serialize", &retval);
zend_call_method_with_0_params_ex(Z_OBJ_P(object), ce, &ce->serialize_func, ZSTR_KNOWN(ZEND_STR_SERIALIZE), &retval);


if (Z_TYPE(retval) == IS_UNDEF || EG(exception)) {
Expand Down Expand Up @@ -439,7 +460,7 @@ ZEND_API int zend_user_unserialize(zval *object, zend_class_entry *ce, const uns

ZVAL_STRINGL(&zdata, (char*)buf, buf_len);

zend_call_method_with_1_params(Z_OBJ_P(object), ce, &ce->unserialize_func, "unserialize", NULL, &zdata);
zend_call_method_with_1_params_ex(Z_OBJ_P(object), ce, &ce->unserialize_func, ZSTR_KNOWN(ZEND_STR_UNSERIALIZE), NULL, &zdata);

zval_ptr_dtor(&zdata);

Expand Down
10 changes: 10 additions & 0 deletions Zend/zend_interfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ typedef struct _zend_user_iterator {
} zend_user_iterator;

ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, zend_function **fn_proxy, const char *function_name, size_t function_name_len, zval *retval, int param_count, zval* arg1, zval* arg2);
ZEND_API zval* zend_call_method_ex(zend_object *object, zend_class_entry *obj_ce, zend_function **fn_proxy, zend_string *function_name, zval *retval_ptr, int param_count, zval* arg1, zval* arg2);

#define zend_call_method_with_0_params(obj, obj_ce, fn_proxy, function_name, retval) \
zend_call_method(obj, obj_ce, fn_proxy, function_name, sizeof(function_name)-1, retval, 0, NULL, NULL)
Expand All @@ -49,6 +50,15 @@ ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, z
#define zend_call_method_with_2_params(obj, obj_ce, fn_proxy, function_name, retval, arg1, arg2) \
zend_call_method(obj, obj_ce, fn_proxy, function_name, sizeof(function_name)-1, retval, 2, arg1, arg2)

#define zend_call_method_with_0_params_ex(obj, obj_ce, fn_proxy, function_name, retval) \
zend_call_method_ex(obj, obj_ce, fn_proxy, function_name, retval, 0, NULL, NULL)

#define zend_call_method_with_1_params_ex(obj, obj_ce, fn_proxy, function_name, retval, arg1) \
zend_call_method_ex(obj, obj_ce, fn_proxy, function_name, retval, 1, arg1, NULL)

#define zend_call_method_with_2_params_ex(obj, obj_ce, fn_proxy, function_name, retval, arg1, arg2) \
zend_call_method_ex(obj, obj_ce, fn_proxy, function_name, retval, 2, arg1, arg2)

#define REGISTER_MAGIC_INTERFACE(class_name, class_name_str) \
{\
zend_class_entry ce;\
Expand Down
16 changes: 8 additions & 8 deletions Zend/zend_object_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ ZEND_API HashTable *zend_std_get_debug_info(zend_object *object, int *is_temp) /
return object->handlers->get_properties(object);
}

zend_call_method_with_0_params(object, ce, &ce->__debugInfo, ZEND_DEBUGINFO_FUNC_NAME, &retval);
zend_call_method_with_0_params_ex(object, ce, &ce->__debugInfo, ZSTR_KNOWN(ZEND_STR_MAGIC_DEBUG_INFO), &retval);
if (Z_TYPE(retval) == IS_ARRAY) {
if (!Z_REFCOUNTED(retval)) {
*is_temp = 1;
Expand Down Expand Up @@ -918,7 +918,7 @@ ZEND_API zval *zend_std_read_dimension(zend_object *object, zval *offset, int ty

GC_ADDREF(object);
if (type == BP_VAR_IS) {
zend_call_method_with_1_params(object, ce, NULL, "offsetexists", rv, &tmp_offset);
zend_call_method_with_1_params_ex(object, ce, NULL, ZSTR_KNOWN(ZEND_STR_OFFSET_EXISTS), rv, &tmp_offset);
if (UNEXPECTED(Z_ISUNDEF_P(rv))) {
OBJ_RELEASE(object);
zval_ptr_dtor(&tmp_offset);
Expand All @@ -933,7 +933,7 @@ ZEND_API zval *zend_std_read_dimension(zend_object *object, zval *offset, int ty
zval_ptr_dtor(rv);
}

zend_call_method_with_1_params(object, ce, NULL, "offsetget", rv, &tmp_offset);
zend_call_method_with_1_params_ex(object, ce, NULL, ZSTR_KNOWN(ZEND_STR_OFFSET_GET), rv, &tmp_offset);

OBJ_RELEASE(object);
zval_ptr_dtor(&tmp_offset);
Expand Down Expand Up @@ -964,7 +964,7 @@ ZEND_API void zend_std_write_dimension(zend_object *object, zval *offset, zval *
ZVAL_COPY_DEREF(&tmp_offset, offset);
}
GC_ADDREF(object);
zend_call_method_with_2_params(object, ce, NULL, "offsetset", NULL, &tmp_offset, value);
zend_call_method_with_2_params_ex(object, ce, NULL, ZSTR_KNOWN(ZEND_STR_OFFSET_SET), NULL, &tmp_offset, value);
OBJ_RELEASE(object);
zval_ptr_dtor(&tmp_offset);
} else {
Expand All @@ -982,11 +982,11 @@ ZEND_API int zend_std_has_dimension(zend_object *object, zval *offset, int check
if (EXPECTED(zend_class_implements_interface(ce, zend_ce_arrayaccess) != 0)) {
ZVAL_COPY_DEREF(&tmp_offset, offset);
GC_ADDREF(object);
zend_call_method_with_1_params(object, ce, NULL, "offsetexists", &retval, &tmp_offset);
zend_call_method_with_1_params_ex(object, ce, NULL, ZSTR_KNOWN(ZEND_STR_OFFSET_EXISTS), &retval, &tmp_offset);
result = i_zend_is_true(&retval);
zval_ptr_dtor(&retval);
if (check_empty && result && EXPECTED(!EG(exception))) {
zend_call_method_with_1_params(object, ce, NULL, "offsetget", &retval, &tmp_offset);
zend_call_method_with_1_params_ex(object, ce, NULL, ZSTR_KNOWN(ZEND_STR_OFFSET_GET), &retval, &tmp_offset);
result = i_zend_is_true(&retval);
zval_ptr_dtor(&retval);
}
Expand Down Expand Up @@ -1138,7 +1138,7 @@ ZEND_API void zend_std_unset_dimension(zend_object *object, zval *offset) /* {{{
if (zend_class_implements_interface(ce, zend_ce_arrayaccess)) {
ZVAL_COPY_DEREF(&tmp_offset, offset);
GC_ADDREF(object);
zend_call_method_with_1_params(object, ce, NULL, "offsetunset", NULL, &tmp_offset);
zend_call_method_with_1_params_ex(object, ce, NULL, ZSTR_KNOWN(ZEND_STR_OFFSET_UNSET), NULL, &tmp_offset);
OBJ_RELEASE(object);
zval_ptr_dtor(&tmp_offset);
} else {
Expand Down Expand Up @@ -1801,7 +1801,7 @@ ZEND_API int zend_std_cast_object_tostring(zend_object *readobj, zval *writeobj,
if (ce->__tostring) {
zval retval;
GC_ADDREF(readobj);
zend_call_method_with_0_params(readobj, ce, &ce->__tostring, "__tostring", &retval);
zend_call_method_with_0_params_ex(readobj, ce, &ce->__tostring, ZSTR_KNOWN(ZEND_STR_MAGIC_TO_STRING), &retval);
zend_object_release(readobj);
if (EXPECTED(Z_TYPE(retval) == IS_STRING)) {
ZVAL_COPY_VALUE(writeobj, &retval);
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ ZEND_API void zend_interned_strings_init(void)
}

/* known strings */
zend_known_strings = pemalloc(sizeof(zend_string*) * ((sizeof(known_strings) / sizeof(known_strings[0]) - 1)), 1);
zend_known_strings = pemalloc(sizeof(zend_string *) * ((sizeof(known_strings) / sizeof(known_strings[0])) - 1), 1);
for (i = 0; i < (sizeof(known_strings) / sizeof(known_strings[0])) - 1; i++) {
str = zend_string_init(known_strings[i], strlen(known_strings[i]), 1);
zend_known_strings[i] = zend_new_interned_string_permanent(str);
Expand Down
Loading