@@ -94,12 +94,11 @@ U_CFUNC TimeZone *timezone_convert_datetimezone(int type,
9494}
9595/* }}} */
9696
97- U_CFUNC int intl_datetime_decompose (zval *z , double *millis, TimeZone **tz,
97+ U_CFUNC zend_result intl_datetime_decompose (zend_object *obj , double *millis, TimeZone **tz,
9898 intl_error *err, const char *func)
9999{
100- zval retval;
101- zval zfuncname;
102100 char *message;
101+ php_date_obj *datetime = php_date_obj_from_obj (obj);
103102
104103 if (err && U_FAILURE (err->code )) {
105104 return FAILURE;
@@ -109,35 +108,35 @@ U_CFUNC int intl_datetime_decompose(zval *z, double *millis, TimeZone **tz,
109108 *millis = ZEND_NAN;
110109 }
111110 if (tz) {
112- *tz = NULL ;
111+ *tz = nullptr ;
113112 }
114113
115114 if (millis) {
116- php_date_obj *datetime;
117-
118- ZVAL_STRING (&zfuncname, " getTimestamp" );
119- if (call_user_function (NULL , z, &zfuncname, &retval, 0 , NULL )
120- != SUCCESS || Z_TYPE (retval) != IS_LONG) {
121- spprintf (&message, 0 , " %s: error calling ::getTimeStamp() on the "
122- " object" , func);
123- intl_errors_set (err, U_INTERNAL_PROGRAM_ERROR,
124- message, 1 );
115+ auto getTimestampMethod = static_cast <zend_function *>(zend_hash_str_find_ptr (&obj->ce ->function_table , ZEND_STRL (" gettimestamp" )));
116+ zval retval;
117+
118+ ZEND_ASSERT (getTimestampMethod && " DateTimeInterface is sealed and thus must have this method" );
119+ zend_call_known_function (getTimestampMethod, obj, obj->ce , &retval, 0 , nullptr , nullptr );
120+
121+ /* An exception has occurred */
122+ if (Z_TYPE (retval) == IS_UNDEF) {
123+ return FAILURE;
124+ }
125+ // TODO: Remove this when DateTimeInterface::getTimestamp() no longer has a tentative return type
126+ if (Z_TYPE (retval) != IS_LONG) {
127+ spprintf (&message, 0 , " %s: %s::getTimestamp() did not return an int" , func, ZSTR_VAL (obj->ce ->name ));
128+ intl_errors_set (err, U_INTERNAL_PROGRAM_ERROR, message, 1 );
125129 efree (message);
126- zval_ptr_dtor (&zfuncname);
127130 return FAILURE;
128131 }
129132
130- datetime = Z_PHPDATE_P (z);
131133 *millis = U_MILLIS_PER_SECOND * (double )Z_LVAL (retval) + (datetime->time ->us / 1000 );
132- zval_ptr_dtor (&zfuncname);
133134 }
134135
135136 if (tz) {
136- php_date_obj *datetime;
137- datetime = Z_PHPDATE_P (z);
138137 if (!datetime->time ) {
139138 spprintf (&message, 0 , " %s: the %s object is not properly "
140- " initialized" , func, ZSTR_VAL (Z_OBJCE_P (z) ->name ));
139+ " initialized" , func, ZSTR_VAL (obj-> ce ->name ));
141140 intl_errors_set (err, U_ILLEGAL_ARGUMENT_ERROR,
142141 message, 1 );
143142 efree (message);
@@ -198,7 +197,7 @@ U_CFUNC double intl_zval_to_millis(zval *z, intl_error *err, const char *func)
198197 break ;
199198 case IS_OBJECT:
200199 if (instanceof_function (Z_OBJCE_P (z), php_date_get_interface_ce ())) {
201- intl_datetime_decompose (z , &rv, NULL , err, func);
200+ intl_datetime_decompose (Z_OBJ_P (z) , &rv, nullptr , err, func);
202201 } else if (instanceof_function (Z_OBJCE_P (z), Calendar_ce_ptr)) {
203202 Calendar_object *co = Z_INTL_CALENDAR_P (z);
204203 if (co->ucal == NULL ) {
0 commit comments