Skip to content

Commit e1dc9d9

Browse files
committed
ext/intl: Separate UConverter object lifecycle from method implementations
1 parent fab508f commit e1dc9d9

5 files changed

Lines changed: 170 additions & 118 deletions

File tree

‎ext/intl/config.m4‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ if test "$PHP_INTL" != "no"; then
3232
common/common_error.cpp \
3333
dateformat/dateformat_class.cpp \
3434
converter/converter.cpp \
35+
converter/converter_class.cpp \
3536
dateformat/dateformat.cpp \
3637
dateformat/dateformat_attr.cpp \
3738
dateformat/dateformat_attrcpp.cpp \

‎ext/intl/config.w32‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ if (PHP_INTL != "no") {
2929
", "intl");
3030
ADD_SOURCES(configure_module_dirname + "/converter", "\
3131
converter.cpp \
32+
converter_class.cpp \
3233
", "intl");
3334
ADD_SOURCES(configure_module_dirname + "/formatter", "\
3435
formatter_attr.cpp \

‎ext/intl/converter/converter.cpp‎

Lines changed: 2 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,14 @@
2020
#include <unicode/ucnv.h>
2121
#include <unicode/ustring.h>
2222

23-
#include "../intl_icu_compat.h"
23+
#include "converter_class.h"
2424

2525
extern "C" {
2626
#include "converter.h"
2727
#include "php_intl.h"
2828
#include "../intl_error.h"
2929
#include "../intl_common.h"
3030
}
31-
#include "converter_arginfo.h"
32-
33-
typedef struct _php_converter_object {
34-
UConverter *src, *dest;
35-
zend_fcall_info_cache to_cache, from_cache;
36-
intl_error error;
37-
zend_object obj;
38-
} php_converter_object;
39-
40-
41-
static inline php_converter_object *php_converter_fetch_object(zend_object *obj) {
42-
return (php_converter_object *)((char*)(obj) - offsetof(php_converter_object, obj));
43-
}
44-
#define Z_INTL_CONVERTER_P(zv) php_converter_fetch_object(Z_OBJ_P(zv))
45-
46-
static zend_class_entry *php_converter_ce;
47-
static zend_object_handlers php_converter_object_handlers;
4831

4932
#define CONV_GET(pzv) (Z_INTL_CONVERTER_P((pzv)))
5033
#define THROW_UFAILURE(obj, error) php_converter_throw_failure(obj, error, \
@@ -332,7 +315,7 @@ static void php_converter_from_u_callback(const void *context,
332315
/* }}} */
333316

334317
/* {{{ php_converter_set_callbacks */
335-
static inline bool php_converter_set_callbacks(php_converter_object *objval, UConverter *cnv) {
318+
bool php_converter_set_callbacks(php_converter_object *objval, UConverter *cnv) {
336319
bool ret = true;
337320
UErrorCode error = U_ZERO_ERROR;
338321

@@ -504,21 +487,6 @@ PHP_METHOD(UConverter, getDestinationType) {
504487
}
505488
/* }}} */
506489

507-
static void php_converter_resolve_callback(
508-
zend_fcall_info_cache *fcc,
509-
zend_object *this_ptr,
510-
const char *callback_name,
511-
size_t callback_name_len
512-
) {
513-
zend_function *fn = reinterpret_cast<zend_function *>(zend_hash_str_find_ptr_lc(&this_ptr->ce->function_table, callback_name, callback_name_len));
514-
ZEND_ASSERT(fn != nullptr);
515-
516-
fcc->function_handler = fn;
517-
fcc->object = this_ptr;
518-
fcc->called_scope = this_ptr->ce;
519-
fcc->closure = nullptr;
520-
}
521-
522490
/* {{{ */
523491
PHP_METHOD(UConverter, __construct) {
524492
php_converter_object *objval = CONV_GET(ZEND_THIS);
@@ -900,87 +868,3 @@ PHP_METHOD(UConverter, getStandards) {
900868
}
901869
}
902870
/* }}} */
903-
904-
/* {{{ Converter create/clone/destroy */
905-
static void php_converter_free_object(zend_object *obj) {
906-
php_converter_object *objval = php_converter_fetch_object(obj);
907-
908-
if (objval->src) {
909-
ucnv_close(objval->src);
910-
}
911-
912-
if (objval->dest) {
913-
ucnv_close(objval->dest);
914-
}
915-
916-
intl_error_reset(&objval->error);
917-
zend_object_std_dtor(obj);
918-
}
919-
920-
static zend_object *php_converter_object_ctor(zend_class_entry *ce, php_converter_object **pobjval) {
921-
php_converter_object *objval;
922-
923-
objval = reinterpret_cast<php_converter_object *>(zend_object_alloc(sizeof(php_converter_object), ce));
924-
925-
zend_object_std_init(&objval->obj, ce);
926-
object_properties_init(&objval->obj, ce);
927-
intl_error_init(&(objval->error));
928-
php_converter_resolve_callback(&objval->to_cache, &objval->obj, ZEND_STRL("toUCallback"));
929-
php_converter_resolve_callback(&objval->from_cache, &objval->obj, ZEND_STRL("fromUCallback"));
930-
931-
*pobjval = objval;
932-
933-
return &objval->obj;
934-
}
935-
936-
static zend_object *php_converter_create_object(zend_class_entry *ce) {
937-
php_converter_object *objval = nullptr;
938-
zend_object *retval = php_converter_object_ctor(ce, &objval);
939-
940-
object_properties_init(&(objval->obj), ce);
941-
942-
return retval;
943-
}
944-
945-
static zend_object *php_converter_clone_object(zend_object *object) {
946-
const php_converter_object *oldobj = php_converter_fetch_object(object);
947-
php_converter_object *objval;
948-
zend_object *retval = php_converter_object_ctor(object->ce, &objval);
949-
UErrorCode error = U_ZERO_ERROR;
950-
951-
objval->src = intl_icu_compat_ucnv_clone(oldobj->src, &error);
952-
if (U_SUCCESS(error)) {
953-
error = U_ZERO_ERROR;
954-
objval->dest = intl_icu_compat_ucnv_clone(oldobj->dest, &error);
955-
}
956-
957-
if (U_FAILURE(error)) {
958-
zend_throw_error(NULL, "Failed to clone UConverter");
959-
return retval;
960-
}
961-
962-
/* Update contexts for converter error handlers */
963-
php_converter_set_callbacks(objval, objval->src );
964-
php_converter_set_callbacks(objval, objval->dest);
965-
966-
zend_objects_clone_members(&(objval->obj), &(oldobj->obj));
967-
968-
/* Newly cloned object deliberately does not inherit error state from original object */
969-
970-
return retval;
971-
}
972-
/* }}} */
973-
974-
/* {{{ php_converter_minit */
975-
U_CFUNC int php_converter_minit(INIT_FUNC_ARGS) {
976-
php_converter_ce = register_class_UConverter();
977-
php_converter_ce->create_object = php_converter_create_object;
978-
php_converter_ce->default_object_handlers = &php_converter_object_handlers;
979-
memcpy(&php_converter_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
980-
php_converter_object_handlers.offset = offsetof(php_converter_object, obj);
981-
php_converter_object_handlers.clone_obj = php_converter_clone_object;
982-
php_converter_object_handlers.free_obj = php_converter_free_object;
983-
984-
return SUCCESS;
985-
}
986-
/* }}} */
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| Copyright © The PHP Group and Contributors. |
4+
+----------------------------------------------------------------------+
5+
| This source file is subject to the Modified BSD License that is |
6+
| bundled with this package in the file LICENSE, and is available |
7+
| through the World Wide Web at <https://www.php.net/license/>. |
8+
| |
9+
| SPDX-License-Identifier: BSD-3-Clause |
10+
+----------------------------------------------------------------------+
11+
| Authors: Sara Golemon <pollita@php.net> |
12+
+----------------------------------------------------------------------+
13+
*/
14+
15+
#include "converter_class.h"
16+
#include "converter.h"
17+
#include "../intl_icu_compat.h"
18+
#include "zend_exceptions.h"
19+
#include "converter_arginfo.h"
20+
21+
zend_class_entry *php_converter_ce;
22+
static zend_object_handlers php_converter_object_handlers;
23+
24+
static void php_converter_resolve_callback(
25+
zend_fcall_info_cache *fcc,
26+
zend_object *this_ptr,
27+
const char *callback_name,
28+
size_t callback_name_len
29+
) {
30+
zend_function *fn = reinterpret_cast<zend_function *>(zend_hash_str_find_ptr_lc(&this_ptr->ce->function_table, callback_name, callback_name_len));
31+
ZEND_ASSERT(fn != nullptr);
32+
33+
fcc->function_handler = fn;
34+
fcc->object = this_ptr;
35+
fcc->called_scope = this_ptr->ce;
36+
fcc->closure = nullptr;
37+
}
38+
39+
/* {{{ Converter create/clone/destroy */
40+
static void php_converter_free_object(zend_object *obj) {
41+
php_converter_object *objval = php_converter_fetch_object(obj);
42+
43+
if (objval->src) {
44+
ucnv_close(objval->src);
45+
}
46+
47+
if (objval->dest) {
48+
ucnv_close(objval->dest);
49+
}
50+
51+
intl_error_reset(&objval->error);
52+
zend_object_std_dtor(obj);
53+
}
54+
55+
static zend_object *php_converter_object_ctor(zend_class_entry *ce, php_converter_object **pobjval) {
56+
php_converter_object *objval;
57+
58+
objval = reinterpret_cast<php_converter_object *>(zend_object_alloc(sizeof(php_converter_object), ce));
59+
60+
zend_object_std_init(&objval->obj, ce);
61+
object_properties_init(&objval->obj, ce);
62+
intl_error_init(&(objval->error));
63+
php_converter_resolve_callback(&objval->to_cache, &objval->obj, ZEND_STRL("toUCallback"));
64+
php_converter_resolve_callback(&objval->from_cache, &objval->obj, ZEND_STRL("fromUCallback"));
65+
66+
*pobjval = objval;
67+
68+
return &objval->obj;
69+
}
70+
71+
static zend_object *php_converter_create_object(zend_class_entry *ce) {
72+
php_converter_object *objval = nullptr;
73+
zend_object *retval = php_converter_object_ctor(ce, &objval);
74+
75+
object_properties_init(&(objval->obj), ce);
76+
77+
return retval;
78+
}
79+
80+
static zend_object *php_converter_clone_object(zend_object *object) {
81+
const php_converter_object *oldobj = php_converter_fetch_object(object);
82+
php_converter_object *objval;
83+
zend_object *retval = php_converter_object_ctor(object->ce, &objval);
84+
UErrorCode error = U_ZERO_ERROR;
85+
86+
objval->src = intl_icu_compat_ucnv_clone(oldobj->src, &error);
87+
if (U_SUCCESS(error)) {
88+
error = U_ZERO_ERROR;
89+
objval->dest = intl_icu_compat_ucnv_clone(oldobj->dest, &error);
90+
}
91+
92+
if (U_FAILURE(error)) {
93+
zend_throw_error(NULL, "Failed to clone UConverter");
94+
return retval;
95+
}
96+
97+
/* Update contexts for converter error handlers */
98+
php_converter_set_callbacks(objval, objval->src );
99+
php_converter_set_callbacks(objval, objval->dest);
100+
101+
zend_objects_clone_members(&(objval->obj), &(oldobj->obj));
102+
103+
/* Newly cloned object deliberately does not inherit error state from original object */
104+
105+
return retval;
106+
}
107+
/* }}} */
108+
109+
/* {{{ php_converter_minit */
110+
U_CFUNC int php_converter_minit(INIT_FUNC_ARGS) {
111+
php_converter_ce = register_class_UConverter();
112+
php_converter_ce->create_object = php_converter_create_object;
113+
php_converter_ce->default_object_handlers = &php_converter_object_handlers;
114+
memcpy(&php_converter_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
115+
php_converter_object_handlers.offset = offsetof(php_converter_object, obj);
116+
php_converter_object_handlers.clone_obj = php_converter_clone_object;
117+
php_converter_object_handlers.free_obj = php_converter_free_object;
118+
119+
return SUCCESS;
120+
}
121+
/* }}} */
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| Copyright © The PHP Group and Contributors. |
4+
+----------------------------------------------------------------------+
5+
| This source file is subject to the Modified BSD License that is |
6+
| bundled with this package in the file LICENSE, and is available |
7+
| through the World Wide Web at <https://www.php.net/license/>. |
8+
| |
9+
| SPDX-License-Identifier: BSD-3-Clause |
10+
+----------------------------------------------------------------------+
11+
| Authors: Sara Golemon <pollita@php.net> |
12+
+----------------------------------------------------------------------+
13+
*/
14+
15+
#ifndef PHP_INTL_CONVERTER_CLASS_H
16+
#define PHP_INTL_CONVERTER_CLASS_H
17+
18+
#include "php.h"
19+
#include <unicode/ucnv.h>
20+
21+
#ifdef __cplusplus
22+
extern "C" {
23+
#endif
24+
#include "../intl_error.h"
25+
#ifdef __cplusplus
26+
}
27+
#endif
28+
29+
typedef struct _php_converter_object {
30+
UConverter *src, *dest;
31+
zend_fcall_info_cache to_cache, from_cache;
32+
intl_error error;
33+
zend_object obj;
34+
} php_converter_object;
35+
36+
static inline php_converter_object *php_converter_fetch_object(zend_object *obj) {
37+
return (php_converter_object *)((char*)(obj) - offsetof(php_converter_object, obj));
38+
}
39+
#define Z_INTL_CONVERTER_P(zv) php_converter_fetch_object(Z_OBJ_P(zv))
40+
41+
extern zend_class_entry *php_converter_ce;
42+
43+
bool php_converter_set_callbacks(php_converter_object *objval, UConverter *cnv);
44+
45+
#endif /* PHP_INTL_CONVERTER_CLASS_H */

0 commit comments

Comments
 (0)