diff --git a/ext/intl/calendar/calendar_class.cpp b/ext/intl/calendar/calendar_class.cpp index 326b5475b73ab..83c5739125fb7 100644 --- a/ext/intl/calendar/calendar_class.cpp +++ b/ext/intl/calendar/calendar_class.cpp @@ -61,7 +61,7 @@ U_CFUNC Calendar *calendar_fetch_native_calendar(zend_object *object) { Calendar_object *co = php_intl_calendar_fetch_object(object); - return co->ucal; + return co->ucal.get(); } U_CFUNC void calendar_object_construct(zval *object, @@ -71,7 +71,7 @@ U_CFUNC void calendar_object_construct(zval *object, CALENDAR_METHOD_FETCH_OBJECT_NO_CHECK; //populate to from object assert(co->ucal == NULL); - co->ucal = calendar; + co->ucal.reset(calendar); } /* {{{ clone handler for Calendar */ @@ -90,7 +90,7 @@ static zend_object *Calendar_clone_obj(zend_object *object) if (UNEXPECTED(!newCalendar)) { zend_throw_error(NULL, "Failed to clone IntlCalendar"); } else { - co_new->ucal = newCalendar; + co_new->ucal.reset(newCalendar); } } else { zend_throw_error(NULL, "Cannot clone uninitialized IntlCalendar"); @@ -143,7 +143,7 @@ static HashTable *Calendar_get_debug_info(zend_object *object, int *is_temp) debug_info = zend_new_array(8); co = php_intl_calendar_fetch_object(object); - cal = co->ucal; + cal = co->ucal.get(); if (cal == NULL) { ZVAL_FALSE(&zv); @@ -221,10 +221,7 @@ static void Calendar_objects_free(zend_object *object) { Calendar_object* co = php_intl_calendar_fetch_object(object); - if (co->ucal) { - delete co->ucal; - co->ucal = NULL; - } + co->ucal.reset(); intl_error_reset(CALENDAR_ERROR_P(co)); zend_object_std_dtor(&co->zo); @@ -237,7 +234,7 @@ static zend_object *Calendar_object_create(zend_class_entry *ce) Calendar_object* intern = (Calendar_object*)zend_object_alloc(sizeof(Calendar_object), ce); zend_object_std_init(&intern->zo, ce); - object_properties_init(&intern->zo, ce); + object_properties_init(&intern->zo, ce); calendar_object_init(intern); return &intern->zo; @@ -250,13 +247,14 @@ static zend_object *Calendar_object_create(zend_class_entry *ce) void calendar_register_IntlCalendar_class(void) { /* Create and register 'IntlCalendar' class. */ + Calendar_object empty; Calendar_ce_ptr = register_class_IntlCalendar(); Calendar_ce_ptr->default_object_handlers = &Calendar_handlers; Calendar_ce_ptr->create_object = Calendar_object_create; memcpy( &Calendar_handlers, &std_object_handlers, sizeof Calendar_handlers); - Calendar_handlers.offset = XtOffsetOf(Calendar_object, zo); + Calendar_handlers.offset = reinterpret_cast(&empty.zo) - reinterpret_cast(&empty); Calendar_handlers.clone_obj = Calendar_clone_obj; Calendar_handlers.get_debug_info = Calendar_get_debug_info; Calendar_handlers.free_obj = Calendar_objects_free; diff --git a/ext/intl/calendar/calendar_class.h b/ext/intl/calendar/calendar_class.h index 167bded8f31b2..c1c111fda1fa7 100644 --- a/ext/intl/calendar/calendar_class.h +++ b/ext/intl/calendar/calendar_class.h @@ -33,13 +33,23 @@ typedef struct { intl_error err; // ICU calendar +#ifndef __cplusplus Calendar* ucal; +#else + std::unique_ptr ucal; +#endif zend_object zo; } Calendar_object; static inline Calendar_object *php_intl_calendar_fetch_object(zend_object *obj) { +#ifndef __cplusplus return (Calendar_object *)((char*)(obj) - XtOffsetOf(Calendar_object, zo)); +#else + Calendar_object empty; + size_t offset = reinterpret_cast(&empty.zo) - reinterpret_cast(&empty); + return reinterpret_cast(reinterpret_cast(obj) - offset); +#endif } #define Z_INTL_CALENDAR_P(zv) php_intl_calendar_fetch_object(Z_OBJ_P(zv)) diff --git a/ext/intl/calendar/calendar_methods.cpp b/ext/intl/calendar/calendar_methods.cpp index 9b7a37c0df523..03cd7c7e35086 100644 --- a/ext/intl/calendar/calendar_methods.cpp +++ b/ext/intl/calendar/calendar_methods.cpp @@ -227,7 +227,7 @@ static void _php_intlcal_field_uec_ret_in32t_method( CALENDAR_METHOD_FETCH_OBJECT; - int32_t result = (co->ucal->*func)( + int32_t result = (co->ucal.get()->*func)( (UCalendarDateFields)field, CALENDAR_ERROR_CODE(co)); INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); @@ -349,7 +349,7 @@ static void _php_intlcal_before_after( RETURN_THROWS(); } - UBool res = (co->ucal->*func)(*when_co->ucal, CALENDAR_ERROR_CODE(co)); + UBool res = (co->ucal.get()->*func)(*when_co->ucal, CALENDAR_ERROR_CODE(co)); INTL_METHOD_CHECK_STATUS(co, "intlcal_before/after: Error calling ICU method"); RETURN_BOOL((int)res); @@ -610,7 +610,7 @@ static void _php_intlcal_field_ret_in32t_method( CALENDAR_METHOD_FETCH_OBJECT; - int32_t result = (co->ucal->*func)((UCalendarDateFields)field); + int32_t result = (co->ucal.get()->*func)((UCalendarDateFields)field); INTL_METHOD_CHECK_STATUS(co, "Call to ICU method has failed"); RETURN_LONG((zend_long)result); diff --git a/ext/intl/calendar/gregoriancalendar_methods.cpp b/ext/intl/calendar/gregoriancalendar_methods.cpp index d1d3e2ceb14e2..2705668062952 100644 --- a/ext/intl/calendar/gregoriancalendar_methods.cpp +++ b/ext/intl/calendar/gregoriancalendar_methods.cpp @@ -46,7 +46,7 @@ using icu::StringPiece; } static inline GregorianCalendar *fetch_greg(Calendar_object *co) { - return static_cast(co->ucal); + return static_cast(co->ucal.get()); } static bool set_gregorian_calendar_time_zone(GregorianCalendar *gcal, UErrorCode status) @@ -204,7 +204,7 @@ static void _php_intlgregcal_constructor_body( } } - co->ucal = gcal.release(); + co->ucal = std::move(gcal); } U_CFUNC PHP_FUNCTION(intlgregcal_create_instance) @@ -256,7 +256,7 @@ U_CFUNC PHP_METHOD(IntlGregorianCalendar, createFromDate) object_init_ex(return_value, GregorianCalendar_ce_ptr); co = Z_INTL_CALENDAR_P(return_value); - co->ucal = gcal.release(); + co->ucal = std::move(gcal); cleanup: zend_restore_error_handling(&error_handling); @@ -304,8 +304,7 @@ U_CFUNC PHP_METHOD(IntlGregorianCalendar, createFromDateTime) object_init_ex(return_value, GregorianCalendar_ce_ptr); co = Z_INTL_CALENDAR_P(return_value); - // TODO: trying to get passed the ownership change step - co->ucal = gcal.release(); + co->ucal = std::move(gcal); cleanup: zend_restore_error_handling(&error_handling);