Skip to content

Commit 021df47

Browse files
committed
Add zend_call_method_ex and use zend_known_strings
1 parent eae3bda commit 021df47

22 files changed

Lines changed: 215 additions & 163 deletions

Zend/zend_exceptions.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -920,7 +920,7 @@ ZEND_API ZEND_COLD void zend_exception_error(zend_object *ex, int severity) /* {
920920
zend_string *str, *file = NULL;
921921
zend_long line = 0;
922922

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

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

947947
if (file) {

Zend/zend_interfaces.c

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,20 @@ ZEND_API zend_class_entry *zend_ce_stringable;
3333
/* {{{ zend_call_method
3434
Only returns the returned zval if retval_ptr != NULL */
3535
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)
36+
{
37+
zend_string *function_name_str;
38+
zval *retval;
39+
40+
function_name_str = zend_string_init(function_name, function_name_len, 0);
41+
retval = zend_call_method_ex(object, obj_ce, fn_proxy, function_name_str, retval_ptr, param_count, arg1, arg2);
42+
zend_string_free(function_name_str);
43+
44+
return retval;
45+
}
46+
/* }}} */
47+
48+
/* {{{ zend_call_method_ex */
49+
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)
3650
{
3751
int result;
3852
zend_fcall_info fci;
@@ -56,9 +70,8 @@ ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, z
5670
if (!fn_proxy && !obj_ce) {
5771
/* no interest in caching and no information already present that is
5872
* needed later inside zend_call_function. */
59-
ZVAL_STRINGL(&fci.function_name, function_name, function_name_len);
73+
ZVAL_STR(&fci.function_name, function_name);
6074
result = zend_call_function(&fci, NULL);
61-
zval_ptr_dtor(&fci.function_name);
6275
} else {
6376
zend_fcall_info_cache fcic;
6477
ZVAL_UNDEF(&fci.function_name); /* Unused */
@@ -68,17 +81,16 @@ ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, z
6881
}
6982
if (!fn_proxy || !*fn_proxy) {
7083
if (EXPECTED(obj_ce)) {
71-
fcic.function_handler = zend_hash_str_find_ptr(
72-
&obj_ce->function_table, function_name, function_name_len);
84+
fcic.function_handler = zend_hash_find_ptr(&obj_ce->function_table, function_name);
7385
if (UNEXPECTED(fcic.function_handler == NULL)) {
7486
/* error at c-level */
75-
zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for method %s::%s", ZSTR_VAL(obj_ce->name), function_name);
87+
zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for method %s::%s", ZSTR_VAL(obj_ce->name), ZSTR_VAL(function_name));
7688
}
7789
} else {
78-
fcic.function_handler = zend_fetch_function_str(function_name, function_name_len);
90+
fcic.function_handler = zend_fetch_function(function_name);
7991
if (UNEXPECTED(fcic.function_handler == NULL)) {
8092
/* error at c-level */
81-
zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for function %s", function_name);
93+
zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for function %s", ZSTR_VAL(function_name));
8294
}
8395
}
8496
if (fn_proxy) {
@@ -110,7 +122,7 @@ ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, z
110122
obj_ce = object ? object->ce : NULL;
111123
}
112124
if (!EG(exception)) {
113-
zend_error_noreturn(E_CORE_ERROR, "Couldn't execute method %s%s%s", obj_ce ? ZSTR_VAL(obj_ce->name) : "", obj_ce ? "::" : "", function_name);
125+
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));
114126
}
115127
}
116128
if (!retval_ptr) {
@@ -126,7 +138,7 @@ ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, z
126138
/* {{{ zend_user_it_new_iterator */
127139
ZEND_API void zend_user_it_new_iterator(zend_class_entry *ce, zval *object, zval *retval)
128140
{
129-
zend_call_method_with_0_params(Z_OBJ_P(object), ce, &ce->iterator_funcs_ptr->zf_new_iterator, "getiterator", retval);
141+
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);
130142
}
131143
/* }}} */
132144

@@ -162,7 +174,7 @@ ZEND_API int zend_user_it_valid(zend_object_iterator *_iter)
162174
zval more;
163175
int result;
164176

165-
zend_call_method_with_0_params(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_valid, "valid", &more);
177+
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);
166178
result = i_zend_is_true(&more);
167179
zval_ptr_dtor(&more);
168180
return result ? SUCCESS : FAILURE;
@@ -178,7 +190,7 @@ ZEND_API zval *zend_user_it_get_current_data(zend_object_iterator *_iter)
178190
zval *object = &iter->it.data;
179191

180192
if (Z_ISUNDEF(iter->value)) {
181-
zend_call_method_with_0_params(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_current, "current", &iter->value);
193+
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);
182194
}
183195
return &iter->value;
184196
}
@@ -191,7 +203,7 @@ ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *ke
191203
zval *object = &iter->it.data;
192204
zval retval;
193205

194-
zend_call_method_with_0_params(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_key, "key", &retval);
206+
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);
195207

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

214226
zend_user_it_invalidate_current(_iter);
215-
zend_call_method_with_0_params(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_next, "next", NULL);
227+
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);
216228
}
217229
/* }}} */
218230

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

225237
zend_user_it_invalidate_current(_iter);
226-
zend_call_method_with_0_params(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_rewind, "rewind", NULL);
238+
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);
227239
}
228240
/* }}} */
229241

@@ -398,7 +410,7 @@ ZEND_API int zend_user_serialize(zval *object, unsigned char **buffer, size_t *b
398410
zval retval;
399411
int result;
400412

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

403415

404416
if (Z_TYPE(retval) == IS_UNDEF || EG(exception)) {
@@ -439,7 +451,7 @@ ZEND_API int zend_user_unserialize(zval *object, zend_class_entry *ce, const uns
439451

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

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

444456
zval_ptr_dtor(&zdata);
445457

Zend/zend_interfaces.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ typedef struct _zend_user_iterator {
3939
} zend_user_iterator;
4040

4141
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);
42+
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);
4243

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

53+
#define zend_call_method_with_0_params_ex(obj, obj_ce, fn_proxy, function_name, retval) \
54+
zend_call_method_ex(obj, obj_ce, fn_proxy, function_name, retval, 0, NULL, NULL)
55+
56+
#define zend_call_method_with_1_params_ex(obj, obj_ce, fn_proxy, function_name, retval, arg1) \
57+
zend_call_method_ex(obj, obj_ce, fn_proxy, function_name, retval, 1, arg1, NULL)
58+
59+
#define zend_call_method_with_2_params_ex(obj, obj_ce, fn_proxy, function_name, retval, arg1, arg2) \
60+
zend_call_method_ex(obj, obj_ce, fn_proxy, function_name, retval, 2, arg1, arg2)
61+
5262
#define REGISTER_MAGIC_INTERFACE(class_name, class_name_str) \
5363
{\
5464
zend_class_entry ce;\

Zend/zend_object_handlers.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ ZEND_API HashTable *zend_std_get_debug_info(zend_object *object, int *is_temp) /
149149
return object->handlers->get_properties(object);
150150
}
151151

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

919919
GC_ADDREF(object);
920920
if (type == BP_VAR_IS) {
921-
zend_call_method_with_1_params(object, ce, NULL, "offsetexists", rv, &tmp_offset);
921+
zend_call_method_with_1_params_ex(object, ce, NULL, ZSTR_KNOWN(ZEND_STR_OFFSET_EXISTS), rv, &tmp_offset);
922922
if (UNEXPECTED(Z_ISUNDEF_P(rv))) {
923923
OBJ_RELEASE(object);
924924
zval_ptr_dtor(&tmp_offset);
@@ -933,7 +933,7 @@ ZEND_API zval *zend_std_read_dimension(zend_object *object, zval *offset, int ty
933933
zval_ptr_dtor(rv);
934934
}
935935

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

938938
OBJ_RELEASE(object);
939939
zval_ptr_dtor(&tmp_offset);
@@ -964,7 +964,7 @@ ZEND_API void zend_std_write_dimension(zend_object *object, zval *offset, zval *
964964
ZVAL_COPY_DEREF(&tmp_offset, offset);
965965
}
966966
GC_ADDREF(object);
967-
zend_call_method_with_2_params(object, ce, NULL, "offsetset", NULL, &tmp_offset, value);
967+
zend_call_method_with_2_params_ex(object, ce, NULL, ZSTR_KNOWN(ZEND_STR_OFFSET_SET), NULL, &tmp_offset, value);
968968
OBJ_RELEASE(object);
969969
zval_ptr_dtor(&tmp_offset);
970970
} else {
@@ -982,11 +982,11 @@ ZEND_API int zend_std_has_dimension(zend_object *object, zval *offset, int check
982982
if (EXPECTED(zend_class_implements_interface(ce, zend_ce_arrayaccess) != 0)) {
983983
ZVAL_COPY_DEREF(&tmp_offset, offset);
984984
GC_ADDREF(object);
985-
zend_call_method_with_1_params(object, ce, NULL, "offsetexists", &retval, &tmp_offset);
985+
zend_call_method_with_1_params_ex(object, ce, NULL, ZSTR_KNOWN(ZEND_STR_OFFSET_EXISTS), &retval, &tmp_offset);
986986
result = i_zend_is_true(&retval);
987987
zval_ptr_dtor(&retval);
988988
if (check_empty && result && EXPECTED(!EG(exception))) {
989-
zend_call_method_with_1_params(object, ce, NULL, "offsetget", &retval, &tmp_offset);
989+
zend_call_method_with_1_params_ex(object, ce, NULL, ZSTR_KNOWN(ZEND_STR_OFFSET_GET), &retval, &tmp_offset);
990990
result = i_zend_is_true(&retval);
991991
zval_ptr_dtor(&retval);
992992
}
@@ -1138,7 +1138,7 @@ ZEND_API void zend_std_unset_dimension(zend_object *object, zval *offset) /* {{{
11381138
if (zend_class_implements_interface(ce, zend_ce_arrayaccess)) {
11391139
ZVAL_COPY_DEREF(&tmp_offset, offset);
11401140
GC_ADDREF(object);
1141-
zend_call_method_with_1_params(object, ce, NULL, "offsetunset", NULL, &tmp_offset);
1141+
zend_call_method_with_1_params_ex(object, ce, NULL, ZSTR_KNOWN(ZEND_STR_OFFSET_UNSET), NULL, &tmp_offset);
11421142
OBJ_RELEASE(object);
11431143
zval_ptr_dtor(&tmp_offset);
11441144
} else {
@@ -1801,7 +1801,7 @@ ZEND_API int zend_std_cast_object_tostring(zend_object *readobj, zval *writeobj,
18011801
if (ce->__tostring) {
18021802
zval retval;
18031803
GC_ADDREF(readobj);
1804-
zend_call_method_with_0_params(readobj, ce, &ce->__tostring, "__tostring", &retval);
1804+
zend_call_method_with_0_params_ex(readobj, ce, &ce->__tostring, ZSTR_KNOWN(ZEND_STR_MAGIC_TO_STRING), &retval);
18051805
zend_object_release(readobj);
18061806
if (EXPECTED(Z_TYPE(retval) == IS_STRING)) {
18071807
ZVAL_COPY_VALUE(writeobj, &retval);

Zend/zend_string.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ ZEND_API void zend_interned_strings_init(void)
104104
}
105105

106106
/* known strings */
107-
zend_known_strings = pemalloc(sizeof(zend_string*) * ((sizeof(known_strings) / sizeof(known_strings[0]) - 1)), 1);
107+
zend_known_strings = pemalloc(sizeof(zend_string *) * ((sizeof(known_strings) / sizeof(known_strings[0])) - 1), 1);
108108
for (i = 0; i < (sizeof(known_strings) / sizeof(known_strings[0])) - 1; i++) {
109109
str = zend_string_init(known_strings[i], strlen(known_strings[i]), 1);
110110
zend_known_strings[i] = zend_new_interned_string_permanent(str);

0 commit comments

Comments
 (0)