]> granicus.if.org Git - php/commitdiff
Add zend_call_known_function() API family
authorNikita Popov <nikita.ppv@gmail.com>
Mon, 8 Jun 2020 15:10:24 +0000 (17:10 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 9 Jun 2020 14:21:54 +0000 (16:21 +0200)
This adds the following APIs:

void zend_call_known_function(
    zend_function *fn, zend_object *object, zend_class_entry *called_scope,
    zval *retval_ptr, int param_count, zval *params);

void zend_call_known_instance_method(
    zend_function *fn, zend_object *object, zval *retval_ptr, int param_count, zval *params);
void zend_call_known_instance_method_with_0_params(
    zend_function *fn, zend_object *object, zval *retval_ptr);
void zend_call_known_instance_method_with_1_params(
    zend_function *fn, zend_object *object, zval *retval_ptr, zval *param);
void zend_call_known_instance_method_with_2_params(
    zend_function *fn, zend_object *object, zval *retval_ptr, zval *param1, zval *param2);

These are used to perform a call if you already have the
zend_function you want to call. zend_call_known_function()
is the base API, the rest are just really thin wrappers around
it for the common case of instance method calls.

Closes GH-5692.

13 files changed:
Zend/zend_API.h
Zend/zend_exceptions.c
Zend/zend_execute_API.c
Zend/zend_interfaces.c
Zend/zend_interfaces.h
Zend/zend_object_handlers.c
Zend/zend_objects.c
ext/intl/calendar/calendar_methods.cpp
ext/intl/timezone/timezone_class.cpp
ext/phar/phar_object.c
ext/reflection/php_reflection.c
sapi/cli/php_cli.c
sapi/phpdbg/phpdbg_prompt.c

index 944bef850dd2526e6fe99fa0b014cec2e6f81111..ae391d98e5bd499773fc933f224b29321bc2067d 100644 (file)
@@ -563,6 +563,37 @@ ZEND_API int zend_fcall_info_call(zend_fcall_info *fci, zend_fcall_info_cache *f
 
 ZEND_API int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache);
 
+/* Call the provided zend_function with the given params.
+ * If retval_ptr is NULL, the return value is discarded.
+ * If object is NULL, this must be a free function or static call.
+ * called_scope must be provided for instance and static method calls. */
+ZEND_API void zend_call_known_function(
+               zend_function *fn, zend_object *object, zend_class_entry *called_scope, zval *retval_ptr,
+               uint32_t param_count, zval *params);
+
+/* Call the provided zend_function instance method on an object. */
+static zend_always_inline void zend_call_known_instance_method(
+               zend_function *fn, zend_object *object, zval *retval_ptr,
+               uint32_t param_count, zval *params)
+{
+       zend_call_known_function(fn, object, object->ce, retval_ptr, param_count, params);
+}
+
+static zend_always_inline void zend_call_known_instance_method_with_0_params(
+               zend_function *fn, zend_object *object, zval *retval_ptr)
+{
+       zend_call_known_instance_method(fn, object, retval_ptr, 0, NULL);
+}
+
+static zend_always_inline void zend_call_known_instance_method_with_1_params(
+               zend_function *fn, zend_object *object, zval *retval_ptr, zval *param)
+{
+       zend_call_known_instance_method(fn, object, retval_ptr, 1, param);
+}
+
+ZEND_API void zend_call_known_instance_method_with_2_params(
+               zend_function *fn, zend_object *object, zval *retval_ptr, zval *param1, zval *param2);
+
 ZEND_API int zend_set_hash_symbol(zval *symbol, const char *name, int name_length, zend_bool is_ref, int num_symbol_tables, ...);
 
 ZEND_API int zend_delete_global_variable(zend_string *name);
index 57eb0108210695339b876a915be730d54995b465..594186682b89e38d62db6af9b56c1c6ee2a2c8c6 100644 (file)
@@ -922,7 +922,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_known_instance_method_with_0_params(ex->ce->__tostring, Z_OBJ(exception), &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));
index 1b48bed125f83aad0782653332987b381da29954..c5626a0df30c9b2c0f0a25118d64fd9d2343657e 100644 (file)
@@ -861,6 +861,51 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /
 }
 /* }}} */
 
+ZEND_API void zend_call_known_function(
+               zend_function *fn, zend_object *object, zend_class_entry *called_scope, zval *retval_ptr,
+               uint32_t param_count, zval *params)
+{
+       zval retval;
+       zend_fcall_info fci;
+       zend_fcall_info_cache fcic;
+
+       ZEND_ASSERT(fn && "zend_function must be passed!");
+
+       fci.size = sizeof(fci);
+       fci.object = object;
+       fci.retval = retval_ptr ? retval_ptr : &retval;
+       fci.param_count = param_count;
+       fci.params = params;
+       fci.no_separation = 1;
+       ZVAL_UNDEF(&fci.function_name); /* Unused */
+
+       fcic.function_handler = fn;
+       fcic.object = object;
+       fcic.called_scope = called_scope;
+
+       int result = zend_call_function(&fci, &fcic);
+       if (UNEXPECTED(result == FAILURE)) {
+               if (!EG(exception)) {
+                       zend_error_noreturn(E_CORE_ERROR, "Couldn't execute method %s%s%s",
+                               fn->common.scope ? ZSTR_VAL(fn->common.scope->name) : "",
+                               fn->common.scope ? "::" : "", ZSTR_VAL(fn->common.function_name));
+               }
+       }
+
+       if (!retval_ptr) {
+               zval_ptr_dtor(&retval);
+       }
+}
+
+ZEND_API void zend_call_known_instance_method_with_2_params(
+               zend_function *fn, zend_object *object, zval *retval_ptr, zval *param1, zval *param2)
+{
+       zval params[2];
+       ZVAL_COPY_VALUE(&params[0], param1);
+       ZVAL_COPY_VALUE(&params[1], param2);
+       zend_call_known_instance_method(fn, object, retval_ptr, 2, params);
+}
+
 ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *key, uint32_t flags) /* {{{ */
 {
        zend_class_entry *ce = NULL;
index 6ad81c08053990a4614ae64d5d16880d8120f277..2a6d70dc581e5cf335f1afad56fc591836280897 100644 (file)
@@ -32,12 +32,10 @@ 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_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, uint32_t param_count, zval* arg1, zval* arg2)
 {
-       int result;
-       zend_fcall_info fci;
-       zend_fcall_info_cache fcic;
-       zval retval;
+       zend_function *fn;
+       zend_class_entry *called_scope;
        zval params[2];
 
        if (param_count > 0) {
@@ -47,68 +45,43 @@ ZEND_API zval* zend_call_method(zend_object *object, zend_class_entry *obj_ce, z
                ZVAL_COPY_VALUE(&params[1], arg2);
        }
 
-       fci.size = sizeof(fci);
-       fci.object = object;
-       fci.retval = retval_ptr ? retval_ptr : &retval;
-       fci.param_count = param_count;
-       fci.params = params;
-       fci.no_separation = 1;
-       ZVAL_UNDEF(&fci.function_name); /* Unused */
-
        if (!obj_ce) {
                obj_ce = object ? object->ce : NULL;
        }
        if (!fn_proxy || !*fn_proxy) {
                if (EXPECTED(obj_ce)) {
-                       fcic.function_handler = zend_hash_str_find_ptr(
+                       fn = zend_hash_str_find_ptr(
                                &obj_ce->function_table, function_name, function_name_len);
-                       if (UNEXPECTED(fcic.function_handler == NULL)) {
+                       if (UNEXPECTED(fn == 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);
                        }
                } else {
-                       fcic.function_handler = zend_fetch_function_str(function_name, function_name_len);
-                       if (UNEXPECTED(fcic.function_handler == NULL)) {
+                       fn = zend_fetch_function_str(function_name, function_name_len);
+                       if (UNEXPECTED(fn == NULL)) {
                                /* error at c-level */
                                zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for function %s", function_name);
                        }
                }
                if (fn_proxy) {
-                       *fn_proxy = fcic.function_handler;
+                       *fn_proxy = fn;
                }
        } else {
-               fcic.function_handler = *fn_proxy;
+               fn = *fn_proxy;
        }
 
        if (object) {
-               fcic.called_scope = object->ce;
+               called_scope = object->ce;
        } else {
-               zend_class_entry *called_scope = zend_get_called_scope(EG(current_execute_data));
-
+               called_scope = zend_get_called_scope(EG(current_execute_data));
                if (obj_ce &&
                        (!called_scope ||
                         !instanceof_function(called_scope, obj_ce))) {
-                       fcic.called_scope = obj_ce;
-               } else {
-                       fcic.called_scope = called_scope;
+                       called_scope = obj_ce;
                }
        }
-       fcic.object = object;
-       result = zend_call_function(&fci, &fcic);
 
-       if (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 (!retval_ptr) {
-               zval_ptr_dtor(&retval);
-               return NULL;
-       }
+       zend_call_known_function(fn, object, called_scope, retval_ptr, param_count, params);
        return retval_ptr;
 }
 /* }}} */
@@ -390,8 +363,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_known_instance_method_with_0_params(ce->serialize_func, Z_OBJ_P(object), &retval);
 
        if (Z_TYPE(retval) == IS_UNDEF || EG(exception)) {
                result = FAILURE;
@@ -430,9 +402,8 @@ 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_known_instance_method_with_1_params(
+               ce->unserialize_func, Z_OBJ_P(object), NULL, &zdata);
        zval_ptr_dtor(&zdata);
 
        if (EG(exception)) {
index dbdcd2a0742a466608765ac5727e532394e6f538..fd3275b2a48e1ad21da0826bd11dbed5fcfe6a24 100644 (file)
@@ -38,7 +38,7 @@ typedef struct _zend_user_iterator {
        zval                     value;
 } 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(zend_object *object, zend_class_entry *obj_ce, zend_function **fn_proxy, const char *function_name, size_t function_name_len, zval *retval, uint32_t 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)
index 4a8b24233aa42b978a89db94d7806428a4613448..05944bbbdf15fb2217453f7e59ed6088a157c1ec 100644 (file)
@@ -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_known_instance_method_with_0_params(ce->__debugInfo, object, &retval);
        if (Z_TYPE(retval) == IS_ARRAY) {
                if (!Z_REFCOUNTED(retval)) {
                        *is_temp = 1;
@@ -177,35 +177,13 @@ ZEND_API HashTable *zend_std_get_debug_info(zend_object *object, int *is_temp) /
 
 static void zend_std_call_getter(zend_object *zobj, zend_string *prop_name, zval *retval) /* {{{ */
 {
-       zend_class_entry *ce = zobj->ce;
        zend_class_entry *orig_fake_scope = EG(fake_scope);
-       zend_fcall_info fci;
-       zend_fcall_info_cache fcic;
        zval member;
 
        EG(fake_scope) = NULL;
 
-       /* __get handler is called with one argument:
-             property name
-
-          it should return whether the call was successful or not
-       */
-
        ZVAL_STR(&member, prop_name);
-
-       fci.size = sizeof(fci);
-       fci.object = zobj;
-       fci.retval = retval;
-       fci.param_count = 1;
-       fci.params = &member;
-       fci.no_separation = 1;
-       ZVAL_UNDEF(&fci.function_name); /* Unused */
-
-       fcic.function_handler = ce->__get;
-       fcic.called_scope = ce;
-       fcic.object = zobj;
-
-       zend_call_function(&fci, &fcic);
+       zend_call_known_instance_method_with_1_params(zobj->ce->__get, zobj, retval, &member);
 
        EG(fake_scope) = orig_fake_scope;
 }
@@ -213,37 +191,14 @@ static void zend_std_call_getter(zend_object *zobj, zend_string *prop_name, zval
 
 static void zend_std_call_setter(zend_object *zobj, zend_string *prop_name, zval *value) /* {{{ */
 {
-       zend_class_entry *ce = zobj->ce;
        zend_class_entry *orig_fake_scope = EG(fake_scope);
-       zend_fcall_info fci;
-       zend_fcall_info_cache fcic;
-       zval args[2], ret;
+       zval args[2];
 
        EG(fake_scope) = NULL;
 
-       /* __set handler is called with two arguments:
-            property name
-            value to be set
-       */
-
        ZVAL_STR(&args[0], prop_name);
        ZVAL_COPY_VALUE(&args[1], value);
-       ZVAL_UNDEF(&ret);
-
-       fci.size = sizeof(fci);
-       fci.object = zobj;
-       fci.retval = &ret;
-       fci.param_count = 2;
-       fci.params = args;
-       fci.no_separation = 1;
-       ZVAL_UNDEF(&fci.function_name); /* Unused */
-
-       fcic.function_handler = ce->__set;
-       fcic.called_scope = ce;
-       fcic.object = zobj;
-
-       zend_call_function(&fci, &fcic);
-       zval_ptr_dtor(&ret);
+       zend_call_known_instance_method(zobj->ce->__set, zobj, NULL, 2, args);
 
        EG(fake_scope) = orig_fake_scope;
 }
@@ -251,35 +206,13 @@ static void zend_std_call_setter(zend_object *zobj, zend_string *prop_name, zval
 
 static void zend_std_call_unsetter(zend_object *zobj, zend_string *prop_name) /* {{{ */
 {
-       zend_class_entry *ce = zobj->ce;
        zend_class_entry *orig_fake_scope = EG(fake_scope);
-       zend_fcall_info fci;
-       zend_fcall_info_cache fcic;
-       zval ret, member;
+       zval member;
 
        EG(fake_scope) = NULL;
 
-       /* __unset handler is called with one argument:
-             property name
-       */
-
        ZVAL_STR(&member, prop_name);
-       ZVAL_UNDEF(&ret);
-
-       fci.size = sizeof(fci);
-       fci.object = zobj;
-       fci.retval = &ret;
-       fci.param_count = 1;
-       fci.params = &member;
-       fci.no_separation = 1;
-       ZVAL_UNDEF(&fci.function_name); /* Unused */
-
-       fcic.function_handler = ce->__unset;
-       fcic.called_scope = ce;
-       fcic.object = zobj;
-
-       zend_call_function(&fci, &fcic);
-       zval_ptr_dtor(&ret);
+       zend_call_known_instance_method_with_1_params(zobj->ce->__unset, zobj, NULL, &member);
 
        EG(fake_scope) = orig_fake_scope;
 }
@@ -287,35 +220,13 @@ static void zend_std_call_unsetter(zend_object *zobj, zend_string *prop_name) /*
 
 static void zend_std_call_issetter(zend_object *zobj, zend_string *prop_name, zval *retval) /* {{{ */
 {
-       zend_class_entry *ce = zobj->ce;
        zend_class_entry *orig_fake_scope = EG(fake_scope);
-       zend_fcall_info fci;
-       zend_fcall_info_cache fcic;
        zval member;
 
        EG(fake_scope) = NULL;
 
-       /* __isset handler is called with one argument:
-             property name
-
-          it should return whether the property is set or not
-       */
-
        ZVAL_STR(&member, prop_name);
-
-       fci.size = sizeof(fci);
-       fci.object = zobj;
-       fci.retval = retval;
-       fci.param_count = 1;
-       fci.params = &member;
-       fci.no_separation = 1;
-       ZVAL_UNDEF(&fci.function_name); /* Unused */
-
-       fcic.function_handler = ce->__isset;
-       fcic.called_scope = ce;
-       fcic.object = zobj;
-
-       zend_call_function(&fci, &fcic);
+       zend_call_known_instance_method_with_1_params(zobj->ce->__isset, zobj, retval, &member);
 
        EG(fake_scope) = orig_fake_scope;
 }
@@ -1803,7 +1714,7 @@ ZEND_API int zend_std_cast_object_tostring(zend_object *readobj, zval *writeobj,
                                zend_class_entry *fake_scope = EG(fake_scope);
                                EG(fake_scope) = NULL;
                                GC_ADDREF(readobj);
-                               zend_call_method_with_0_params(readobj, ce, &ce->__tostring, "__tostring", &retval);
+                               zend_call_known_instance_method_with_0_params(ce->__tostring, readobj, &retval);
                                zend_object_release(readobj);
                                EG(fake_scope) = fake_scope;
                                if (EXPECTED(Z_TYPE(retval) == IS_STRING)) {
index 13a6b45a7ca0e60e22d87b916443c34fdaf62903..f25983ece3fbf2e7b2d3177f72a7e112625d6b3c 100644 (file)
@@ -98,9 +98,6 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
        if (destructor) {
                zend_object *old_exception;
                zend_class_entry *orig_fake_scope;
-               zend_fcall_info fci;
-               zend_fcall_info_cache fcic;
-               zval ret;
 
                if (destructor->op_array.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) {
                        if (destructor->op_array.fn_flags & ZEND_ACC_PRIVATE) {
@@ -162,22 +159,7 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
                orig_fake_scope = EG(fake_scope);
                EG(fake_scope) = NULL;
 
-               ZVAL_UNDEF(&ret);
-
-               fci.size = sizeof(fci);
-               fci.object = object;
-               fci.retval = &ret;
-               fci.param_count = 0;
-               fci.params = NULL;
-               fci.no_separation = 1;
-               ZVAL_UNDEF(&fci.function_name); /* Unused */
-
-               fcic.function_handler = destructor;
-               fcic.called_scope = object->ce;
-               fcic.object = object;
-
-               zend_call_function(&fci, &fcic);
-               zval_ptr_dtor(&ret);
+               zend_call_known_instance_method_with_0_params(destructor, object, NULL);
 
                if (old_exception) {
                        if (EG(exception)) {
@@ -264,28 +246,8 @@ ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object,
        }
 
        if (old_object->ce->clone) {
-               zend_fcall_info fci;
-               zend_fcall_info_cache fcic;
-               zval ret;
-
                GC_ADDREF(new_object);
-
-               ZVAL_UNDEF(&ret);
-
-               fci.size = sizeof(fci);
-               fci.object = new_object;
-               fci.retval = &ret;
-               fci.param_count = 0;
-               fci.params = NULL;
-               fci.no_separation = 1;
-               ZVAL_UNDEF(&fci.function_name); /* Unused */
-
-               fcic.function_handler = new_object->ce->clone;
-               fcic.called_scope = new_object->ce;
-               fcic.object = new_object;
-
-               zend_call_function(&fci, &fcic);
-               zval_ptr_dtor(&ret);
+               zend_call_known_instance_method_with_0_params(new_object->ce->clone, new_object, NULL);
                OBJ_RELEASE(new_object);
        }
 }
index 45fe97d509121876ba2d7ca3cad0cd0ef495b106..186c2597f427d8a94af67e17a0668c9383fb9f1d 100644 (file)
@@ -1016,7 +1016,8 @@ U_CFUNC PHP_FUNCTION(intlcal_from_date_time)
        if (!(Z_TYPE_P(zv_arg) == IS_OBJECT && instanceof_function(
                        Z_OBJCE_P(zv_arg), php_date_get_date_ce()))) {
                object_init_ex(&zv_tmp, php_date_get_date_ce());
-               zend_call_method_with_1_params(Z_OBJ(zv_tmp), NULL, &Z_OBJCE(zv_tmp)->constructor, "__construct", NULL, zv_arg);
+               zend_call_known_instance_method_with_1_params(
+                       Z_OBJCE(zv_tmp)->constructor, Z_OBJ(zv_tmp), NULL, zv_arg);
                zv_datetime = &zv_tmp;
                if (EG(exception)) {
                        zend_object_store_ctor_failed(Z_OBJ(zv_tmp));
@@ -1130,7 +1131,8 @@ U_CFUNC PHP_FUNCTION(intlcal_to_date_time)
 
        /* Finally, instantiate object and call constructor */
        object_init_ex(return_value, php_date_get_date_ce());
-       zend_call_method_with_2_params(Z_OBJ_P(return_value), NULL, &Z_OBJCE_P(return_value)->constructor, "__construct", NULL, &ts_zval, timezone_zval);
+       zend_call_known_instance_method_with_2_params(
+               Z_OBJCE_P(return_value)->constructor, Z_OBJ_P(return_value), NULL, &ts_zval, timezone_zval);
        if (EG(exception)) {
                intl_errors_set(CALENDAR_ERROR_P(co), U_ILLEGAL_ARGUMENT_ERROR,
                        "intlcal_to_date_time: DateTime constructor has thrown exception",
index b3d447f5d51a0d4c6689982a87ba39163e0a3575..63d5b057467fd6c952bbc2b32405d21e5c3ba04b 100644 (file)
@@ -96,7 +96,8 @@ U_CFUNC zval *timezone_convert_to_datetimezone(const TimeZone *timeZone,
                        goto error;
                }
                ZVAL_STR(&arg, u8str);
-               zend_call_method_with_1_params(Z_OBJ_P(ret), NULL, &Z_OBJCE_P(ret)->constructor, "__construct", NULL, &arg);
+               zend_call_known_instance_method_with_1_params(
+                       Z_OBJCE_P(ret)->constructor, Z_OBJ_P(ret), NULL, &arg);
                if (EG(exception)) {
                        spprintf(&message, 0,
                                "%s: DateTimeZone constructor threw exception", func);
index 351d342c53a9ad80ab257231e4df19a950728fb2..d273e1d519c22d19efa1dc34bce4fd1119005f72 100644 (file)
@@ -1242,8 +1242,8 @@ PHP_METHOD(Phar, __construct)
        ZVAL_STRINGL(&arg1, fname, fname_len);
        ZVAL_LONG(&arg2, flags);
 
-       zend_call_method_with_2_params(Z_OBJ_P(zobj), Z_OBJCE_P(zobj),
-               &spl_ce_RecursiveDirectoryIterator->constructor, "__construct", NULL, &arg1, &arg2);
+       zend_call_known_instance_method_with_2_params(spl_ce_RecursiveDirectoryIterator->constructor,
+               Z_OBJ_P(zobj), NULL, &arg1, &arg2);
 
        zval_ptr_dtor(&arg1);
 
@@ -1764,8 +1764,8 @@ PHP_METHOD(Phar, buildFromDirectory)
        ZVAL_STRINGL(&arg, dir, dir_len);
        ZVAL_LONG(&arg2, SPL_FILE_DIR_SKIPDOTS|SPL_FILE_DIR_UNIXPATHS);
 
-       zend_call_method_with_2_params(Z_OBJ(iter), spl_ce_RecursiveDirectoryIterator,
-                       &spl_ce_RecursiveDirectoryIterator->constructor, "__construct", NULL, &arg, &arg2);
+       zend_call_known_instance_method_with_2_params(spl_ce_RecursiveDirectoryIterator->constructor,
+               Z_OBJ(iter), NULL, &arg, &arg2);
 
        zval_ptr_dtor(&arg);
        if (EG(exception)) {
@@ -1780,8 +1780,8 @@ PHP_METHOD(Phar, buildFromDirectory)
                RETURN_THROWS();
        }
 
-       zend_call_method_with_1_params(Z_OBJ(iteriter), spl_ce_RecursiveIteratorIterator,
-                       &spl_ce_RecursiveIteratorIterator->constructor, "__construct", NULL, &iter);
+       zend_call_known_instance_method_with_1_params(spl_ce_RecursiveIteratorIterator->constructor,
+               Z_OBJ(iteriter), NULL, &iter);
 
        if (EG(exception)) {
                zval_ptr_dtor(&iter);
@@ -1803,8 +1803,8 @@ PHP_METHOD(Phar, buildFromDirectory)
 
                ZVAL_STRINGL(&arg2, regex, regex_len);
 
-               zend_call_method_with_2_params(Z_OBJ(regexiter), spl_ce_RegexIterator,
-                       &spl_ce_RegexIterator->constructor, "__construct", NULL, &iteriter, &arg2);
+               zend_call_known_instance_method_with_2_params(spl_ce_RegexIterator->constructor,
+                       Z_OBJ(regexiter), NULL, &iteriter, &arg2);
                zval_ptr_dtor(&arg2);
        }
 
@@ -2256,7 +2256,7 @@ its_ok:
 
        ZVAL_STRINGL(&arg1, phar->fname, phar->fname_len);
 
-       zend_call_method_with_1_params(Z_OBJ(ret), ce, &ce->constructor, "__construct", NULL, &arg1);
+       zend_call_known_instance_method_with_1_params(ce->constructor, Z_OBJ(ret), NULL, &arg1);
        zval_ptr_dtor(&arg1);
        return Z_OBJ(ret);
 }
@@ -4539,8 +4539,8 @@ PHP_METHOD(PharFileInfo, __construct)
 
        ZVAL_STRINGL(&arg1, fname, fname_len);
 
-       zend_call_method_with_1_params(Z_OBJ_P(zobj), Z_OBJCE_P(zobj),
-               &spl_ce_SplFileInfo->constructor, "__construct", NULL, &arg1);
+       zend_call_known_instance_method_with_1_params(spl_ce_SplFileInfo->constructor,
+               Z_OBJ_P(zobj), NULL, &arg1);
 
        zval_ptr_dtor(&arg1);
 }
index e7296b800885d0dc9ef68f2182a28b78569d3a86..1f29ff59e48925d3f47f46ef2186229f491ea976 100644 (file)
@@ -4754,7 +4754,6 @@ ZEND_METHOD(ReflectionClass, isInstance)
    Returns an instance of this class */
 ZEND_METHOD(ReflectionClass, newInstance)
 {
-       zval retval;
        reflection_object *intern;
        zend_class_entry *ce, *old_scope;
        zend_function *constructor;
@@ -4773,9 +4772,7 @@ ZEND_METHOD(ReflectionClass, newInstance)
        /* Run the constructor if there is one */
        if (constructor) {
                zval *params = NULL;
-               int ret, i, num_args = 0;
-               zend_fcall_info fci;
-               zend_fcall_info_cache fcc;
+               int i, num_args = 0;
 
                if (!(constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
                        zend_throw_exception_ex(reflection_exception_ptr, 0, "Access to non-public constructor of class %s", ZSTR_VAL(ce->name));
@@ -4792,20 +4789,8 @@ ZEND_METHOD(ReflectionClass, newInstance)
                        Z_TRY_ADDREF(params[i]);
                }
 
-               fci.size = sizeof(fci);
-               ZVAL_UNDEF(&fci.function_name);
-               fci.object = Z_OBJ_P(return_value);
-               fci.retval = &retval;
-               fci.param_count = num_args;
-               fci.params = params;
-               fci.no_separation = 1;
-
-               fcc.function_handler = constructor;
-               fcc.called_scope = Z_OBJCE_P(return_value);
-               fcc.object = Z_OBJ_P(return_value);
+               zend_call_known_instance_method(constructor, Z_OBJ_P(return_value), NULL, num_args, params);
 
-               ret = zend_call_function(&fci, &fcc);
-               zval_ptr_dtor(&retval);
                for (i = 0; i < num_args; i++) {
                        zval_ptr_dtor(&params[i]);
                }
@@ -4813,11 +4798,6 @@ ZEND_METHOD(ReflectionClass, newInstance)
                if (EG(exception)) {
                        zend_object_store_ctor_failed(Z_OBJ_P(return_value));
                }
-               if (ret == FAILURE) {
-                       php_error_docref(NULL, E_WARNING, "Invocation of %s's constructor failed", ZSTR_VAL(ce->name));
-                       zval_ptr_dtor(return_value);
-                       RETURN_NULL();
-               }
        } else if (ZEND_NUM_ARGS()) {
                zend_throw_exception_ex(reflection_exception_ptr, 0, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ZSTR_VAL(ce->name));
        }
@@ -4851,10 +4831,10 @@ ZEND_METHOD(ReflectionClass, newInstanceWithoutConstructor)
    Returns an instance of this class */
 ZEND_METHOD(ReflectionClass, newInstanceArgs)
 {
-       zval retval, *val;
+       zval *val;
        reflection_object *intern;
        zend_class_entry *ce, *old_scope;
-       int ret, i, argc = 0;
+       int i, argc = 0;
        HashTable *args;
        zend_function *constructor;
 
@@ -4880,8 +4860,6 @@ ZEND_METHOD(ReflectionClass, newInstanceArgs)
        /* Run the constructor if there is one */
        if (constructor) {
                zval *params = NULL;
-               zend_fcall_info fci;
-               zend_fcall_info_cache fcc;
 
                if (!(constructor->common.fn_flags & ZEND_ACC_PUBLIC)) {
                        zend_throw_exception_ex(reflection_exception_ptr, 0, "Access to non-public constructor of class %s", ZSTR_VAL(ce->name));
@@ -4898,20 +4876,8 @@ ZEND_METHOD(ReflectionClass, newInstanceArgs)
                        } ZEND_HASH_FOREACH_END();
                }
 
-               fci.size = sizeof(fci);
-               ZVAL_UNDEF(&fci.function_name);
-               fci.object = Z_OBJ_P(return_value);
-               fci.retval = &retval;
-               fci.param_count = argc;
-               fci.params = params;
-               fci.no_separation = 1;
+               zend_call_known_instance_method(constructor, Z_OBJ_P(return_value), NULL, argc, params);
 
-               fcc.function_handler = constructor;
-               fcc.called_scope = Z_OBJCE_P(return_value);
-               fcc.object = Z_OBJ_P(return_value);
-
-               ret = zend_call_function(&fci, &fcc);
-               zval_ptr_dtor(&retval);
                if (params) {
                        for (i = 0; i < argc; i++) {
                                zval_ptr_dtor(&params[i]);
@@ -4922,12 +4888,6 @@ ZEND_METHOD(ReflectionClass, newInstanceArgs)
                if (EG(exception)) {
                        zend_object_store_ctor_failed(Z_OBJ_P(return_value));
                }
-               if (ret == FAILURE) {
-                       zval_ptr_dtor(&retval);
-                       php_error_docref(NULL, E_WARNING, "Invocation of %s's constructor failed", ZSTR_VAL(ce->name));
-                       zval_ptr_dtor(return_value);
-                       RETURN_NULL();
-               }
        } else if (argc) {
                zend_throw_exception_ex(reflection_exception_ptr, 0, "Class %s does not have a constructor, so you cannot pass any constructor arguments", ZSTR_VAL(ce->name));
        }
@@ -6487,15 +6447,7 @@ ZEND_METHOD(ReflectionAttribute, getArguments)
 
 static int call_attribute_constructor(zend_class_entry *ce, zend_object *obj, zval *args, uint32_t argc) /* {{{ */
 {
-       zend_fcall_info fci;
-       zend_fcall_info_cache fcc;
-
-       zend_function *ctor;
-       zval retval;
-       int ret;
-
-       ctor = ce->constructor;
-
+       zend_function *ctor = ce->constructor;
        ZEND_ASSERT(ctor != NULL);
 
        if (!(ctor->common.fn_flags & ZEND_ACC_PUBLIC)) {
@@ -6503,31 +6455,13 @@ static int call_attribute_constructor(zend_class_entry *ce, zend_object *obj, zv
                return FAILURE;
        }
 
-       fci.size = sizeof(fci);
-       ZVAL_UNDEF(&fci.function_name);
-       fci.object = obj;
-       fci.retval = &retval;
-       fci.params = args;
-       fci.param_count = argc;
-       fci.no_separation = 1;
-
-       fcc.function_handler = ctor;
-       fcc.called_scope = ce;
-       fcc.object = obj;
-
-       ret = zend_call_function(&fci, &fcc);
-
+       zend_call_known_instance_method(ctor, obj, NULL, argc, args);
        if (EG(exception)) {
                zend_object_store_ctor_failed(obj);
+               return FAILURE;
        }
 
-       zval_ptr_dtor(&retval);
-
-       if (ret != SUCCESS) {
-               zend_throw_error(NULL, "Failed to invoke constructor of attribute class '%s'", ZSTR_VAL(ce->name));
-       }
-
-       return EG(exception) ? FAILURE : SUCCESS;
+       return SUCCESS;
 }
 /* }}} */
 
index 206d393b7e8cad78ad092006d084e57f16507b9f..a9069c6191afb8dc02a28fd1305a461632df07c2 100644 (file)
@@ -1070,7 +1070,8 @@ static int do_cli(int argc, char **argv) /* {{{ */
 
                                        memset(&execute_data, 0, sizeof(zend_execute_data));
                                        EG(current_execute_data) = &execute_data;
-                                       zend_call_method_with_1_params(Z_OBJ(ref), pce, &pce->constructor, "__construct", NULL, &arg);
+                                       zend_call_known_instance_method_with_1_params(
+                                               pce->constructor, Z_OBJ(ref), NULL, &arg);
 
                                        if (EG(exception)) {
                                                zval tmp, *msg, rv;
index 14e09d72432f8b9311b4b47d4a7acd5fa0eddec9..2f0e8e2440b606eab19ebd48452370d458c0b8f6 100644 (file)
@@ -726,7 +726,7 @@ static inline void phpdbg_handle_exception(void) /* {{{ */
        EG(exception) = NULL;
 
        ZVAL_OBJ(&zv, ex);
-       zend_call_method_with_0_params(ex, ex->ce, &ex->ce->__tostring, "__tostring", &tmp);
+       zend_call_known_instance_method_with_0_params(ex->ce->__tostring, ex, &tmp);
        file = zval_get_string(zend_read_property(zend_get_exception_base(&zv), &zv, ZEND_STRL("file"), 1, &rv));
        line = zval_get_long(zend_read_property(zend_get_exception_base(&zv), &zv, ZEND_STRL("line"), 1, &rv));