Skip to content

Commit 10b1ab9

Browse files
committed
Some reflection cleanups
Use zend_string and zend_string_tolower in more places, clean up __invoke handling slightly.
1 parent 784579d commit 10b1ab9

File tree

1 file changed

+35
-55
lines changed

1 file changed

+35
-55
lines changed

ext/reflection/php_reflection.c

Lines changed: 35 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,11 @@ static inline reflection_object *reflection_object_from_obj(zend_object *obj) {
150150

151151
static zend_object_handlers reflection_object_handlers;
152152

153+
static inline zend_bool is_closure_invoke(zend_class_entry *ce, zend_string *lcname) {
154+
return ce == zend_ce_closure
155+
&& zend_string_equals_literal(lcname, ZEND_INVOKE_FUNC_NAME);
156+
}
157+
153158
static zval *_default_load_name(zval *object) /* {{{ */
154159
{
155160
return zend_hash_find_ex_ind(Z_OBJPROP_P(object), ZSTR_KNOWN(ZEND_STR_NAME), 1);
@@ -474,8 +479,7 @@ static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char
474479
{
475480
zend_function *closure;
476481
/* see if this is a closure */
477-
if (ce == zend_ce_closure && obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
478-
&& memcmp(ZSTR_VAL(mptr->common.function_name), ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
482+
if (obj && is_closure_invoke(ce, mptr->common.function_name)
479483
&& (closure = zend_get_closure_invoke_method(Z_OBJ_P(obj))) != NULL)
480484
{
481485
mptr = closure;
@@ -2268,30 +2272,26 @@ ZEND_METHOD(reflection_parameter, __construct)
22682272

22692273
/* First, find the function */
22702274
switch (Z_TYPE_P(reference)) {
2271-
case IS_STRING: {
2272-
size_t lcname_len;
2273-
char *lcname;
2274-
2275-
lcname_len = Z_STRLEN_P(reference);
2276-
lcname = zend_str_tolower_dup(Z_STRVAL_P(reference), lcname_len);
2277-
if ((fptr = zend_hash_str_find_ptr(EG(function_table), lcname, lcname_len)) == NULL) {
2278-
efree(lcname);
2275+
case IS_STRING:
2276+
{
2277+
zend_string *lcname = zend_string_tolower(Z_STR_P(reference));
2278+
fptr = zend_hash_find_ptr(EG(function_table), lcname);
2279+
zend_string_release(lcname);
2280+
if (!fptr) {
22792281
zend_throw_exception_ex(reflection_exception_ptr, 0,
22802282
"Function %s() does not exist", Z_STRVAL_P(reference));
22812283
return;
22822284
}
2283-
efree(lcname);
2285+
ce = fptr->common.scope;
22842286
}
2285-
ce = fptr->common.scope;
22862287
break;
22872288

22882289
case IS_ARRAY: {
22892290
zval *classref;
22902291
zval *method;
2291-
size_t lcname_len;
2292-
char *lcname;
2292+
zend_string *lcname;
22932293

2294-
if (((classref =zend_hash_index_find(Z_ARRVAL_P(reference), 0)) == NULL)
2294+
if (((classref = zend_hash_index_find(Z_ARRVAL_P(reference), 0)) == NULL)
22952295
|| ((method = zend_hash_index_find(Z_ARRVAL_P(reference), 1)) == NULL))
22962296
{
22972297
_DO_THROW("Expected array($object, $method) or array($classname, $method)");
@@ -2310,22 +2310,19 @@ ZEND_METHOD(reflection_parameter, __construct)
23102310
}
23112311

23122312
convert_to_string_ex(method);
2313-
lcname_len = Z_STRLEN_P(method);
2314-
lcname = zend_str_tolower_dup(Z_STRVAL_P(method), lcname_len);
2315-
if (ce == zend_ce_closure && Z_TYPE_P(classref) == IS_OBJECT
2316-
&& (lcname_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
2317-
&& memcmp(lcname, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
2313+
lcname = zend_string_tolower(Z_STR_P(method));
2314+
if (Z_TYPE_P(classref) == IS_OBJECT && is_closure_invoke(ce, lcname)
23182315
&& (fptr = zend_get_closure_invoke_method(Z_OBJ_P(classref))) != NULL)
23192316
{
23202317
/* nothing to do. don't set is_closure since is the invoke handler,
23212318
not the closure itself */
2322-
} else if ((fptr = zend_hash_str_find_ptr(&ce->function_table, lcname, lcname_len)) == NULL) {
2323-
efree(lcname);
2319+
} else if ((fptr = zend_hash_find_ptr(&ce->function_table, lcname)) == NULL) {
2320+
zend_string_release(lcname);
23242321
zend_throw_exception_ex(reflection_exception_ptr, 0,
23252322
"Method %s::%s() does not exist", ZSTR_VAL(ce->name), Z_STRVAL_P(method));
23262323
return;
23272324
}
2328-
efree(lcname);
2325+
zend_string_release(lcname);
23292326
}
23302327
break;
23312328

@@ -2336,7 +2333,7 @@ ZEND_METHOD(reflection_parameter, __construct)
23362333
fptr = (zend_function *)zend_get_closure_method_def(reference);
23372334
Z_ADDREF_P(reference);
23382335
is_closure = 1;
2339-
} else if ((fptr = zend_hash_str_find_ptr(&ce->function_table, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME))) == NULL) {
2336+
} else if ((fptr = zend_hash_find_ptr(&ce->function_table, ZSTR_KNOWN(ZEND_STR_MAGIC_INVOKE))) == NULL) {
23402337
zend_throw_exception_ex(reflection_exception_ptr, 0,
23412338
"Method %s::%s() does not exist", ZSTR_VAL(ce->name), ZEND_INVOKE_FUNC_NAME);
23422339
return;
@@ -4070,24 +4067,16 @@ ZEND_METHOD(reflection_class, hasMethod)
40704067
{
40714068
reflection_object *intern;
40724069
zend_class_entry *ce;
4073-
char *name, *lc_name;
4074-
size_t name_len;
4070+
zend_string *name, *lc_name;
40754071

4076-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
4072+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) {
40774073
return;
40784074
}
40794075

40804076
GET_REFLECTION_OBJECT_PTR(ce);
4081-
lc_name = zend_str_tolower_dup(name, name_len);
4082-
if ((ce == zend_ce_closure && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
4083-
&& memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0)
4084-
|| zend_hash_str_exists(&ce->function_table, lc_name, name_len)) {
4085-
efree(lc_name);
4086-
RETURN_TRUE;
4087-
} else {
4088-
efree(lc_name);
4089-
RETURN_FALSE;
4090-
}
4077+
lc_name = zend_string_tolower(name);
4078+
RETVAL_BOOL(zend_hash_exists(&ce->function_table, lc_name) || is_closure_invoke(ce, lc_name));
4079+
zend_string_release(lc_name);
40914080
}
40924081
/* }}} */
40934082

@@ -4099,52 +4088,43 @@ ZEND_METHOD(reflection_class, getMethod)
40994088
zend_class_entry *ce;
41004089
zend_function *mptr;
41014090
zval obj_tmp;
4102-
char *name, *lc_name;
4103-
size_t name_len;
4091+
zend_string *name, *lc_name;
41044092

4105-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &name, &name_len) == FAILURE) {
4093+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &name) == FAILURE) {
41064094
return;
41074095
}
41084096

41094097
GET_REFLECTION_OBJECT_PTR(ce);
4110-
lc_name = zend_str_tolower_dup(name, name_len);
4111-
if (ce == zend_ce_closure && !Z_ISUNDEF(intern->obj) && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
4112-
&& memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
4098+
lc_name = zend_string_tolower(name);
4099+
if (!Z_ISUNDEF(intern->obj) && is_closure_invoke(ce, lc_name)
41134100
&& (mptr = zend_get_closure_invoke_method(Z_OBJ(intern->obj))) != NULL)
41144101
{
41154102
/* don't assign closure_object since we only reflect the invoke handler
41164103
method and not the closure definition itself */
41174104
reflection_method_factory(ce, mptr, NULL, return_value);
4118-
efree(lc_name);
4119-
} else if (ce == zend_ce_closure && Z_ISUNDEF(intern->obj) && (name_len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
4120-
&& memcmp(lc_name, ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
4105+
} else if (Z_ISUNDEF(intern->obj) && is_closure_invoke(ce, lc_name)
41214106
&& object_init_ex(&obj_tmp, ce) == SUCCESS && (mptr = zend_get_closure_invoke_method(Z_OBJ(obj_tmp))) != NULL) {
41224107
/* don't assign closure_object since we only reflect the invoke handler
41234108
method and not the closure definition itself */
41244109
reflection_method_factory(ce, mptr, NULL, return_value);
41254110
zval_ptr_dtor(&obj_tmp);
4126-
efree(lc_name);
4127-
} else if ((mptr = zend_hash_str_find_ptr(&ce->function_table, lc_name, name_len)) != NULL) {
4111+
} else if ((mptr = zend_hash_find_ptr(&ce->function_table, lc_name)) != NULL) {
41284112
reflection_method_factory(ce, mptr, NULL, return_value);
4129-
efree(lc_name);
41304113
} else {
4131-
efree(lc_name);
41324114
zend_throw_exception_ex(reflection_exception_ptr, 0,
4133-
"Method %s does not exist", name);
4134-
return;
4115+
"Method %s does not exist", ZSTR_VAL(name));
41354116
}
4117+
zend_string_release(lc_name);
41364118
}
41374119
/* }}} */
41384120

41394121
/* {{{ _addmethod */
41404122
static void _addmethod(zend_function *mptr, zend_class_entry *ce, zval *retval, zend_long filter, zval *obj)
41414123
{
41424124
zval method;
4143-
size_t len = ZSTR_LEN(mptr->common.function_name);
41444125
zend_function *closure;
41454126
if (mptr->common.fn_flags & filter) {
4146-
if (ce == zend_ce_closure && obj && (len == sizeof(ZEND_INVOKE_FUNC_NAME)-1)
4147-
&& memcmp(ZSTR_VAL(mptr->common.function_name), ZEND_INVOKE_FUNC_NAME, sizeof(ZEND_INVOKE_FUNC_NAME)-1) == 0
4127+
if (obj && is_closure_invoke(ce, mptr->common.function_name)
41484128
&& (closure = zend_get_closure_invoke_method(Z_OBJ_P(obj))) != NULL)
41494129
{
41504130
mptr = closure;

0 commit comments

Comments
 (0)