Skip to content

Commit 5456a6e

Browse files
rjhdbynikic
authored andcommitted
Deduplicate code in zend_builtin_functions.c
1 parent e528762 commit 5456a6e

File tree

1 file changed

+74
-149
lines changed

1 file changed

+74
-149
lines changed

Zend/zend_builtin_functions.c

Lines changed: 74 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ ZEND_MINIT_FUNCTION(core) { /* {{{ */
311311
/* }}} */
312312

313313
zend_module_entry zend_builtin_module = { /* {{{ */
314-
STANDARD_MODULE_HEADER,
314+
STANDARD_MODULE_HEADER,
315315
"Core",
316316
builtin_functions,
317317
ZEND_MINIT(core),
@@ -1010,7 +1010,7 @@ ZEND_FUNCTION(get_parent_class)
10101010
if (Z_TYPE_P(arg) == IS_OBJECT) {
10111011
ce = Z_OBJ_P(arg)->ce;
10121012
} else if (Z_TYPE_P(arg) == IS_STRING) {
1013-
ce = zend_lookup_class(Z_STR_P(arg));
1013+
ce = zend_lookup_class(Z_STR_P(arg));
10141014
}
10151015

10161016
if (ce && ce->parent) {
@@ -1098,9 +1098,9 @@ static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, int st
10981098

10991099
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) {
11001100
if (((prop_info->flags & ZEND_ACC_PROTECTED) &&
1101-
!zend_check_protected(prop_info->ce, scope)) ||
1102-
((prop_info->flags & ZEND_ACC_PRIVATE) &&
1103-
prop_info->ce != scope)) {
1101+
!zend_check_protected(prop_info->ce, scope)) ||
1102+
((prop_info->flags & ZEND_ACC_PRIVATE) &&
1103+
prop_info->ce != scope)) {
11041104
continue;
11051105
}
11061106
prop = NULL;
@@ -1267,7 +1267,7 @@ ZEND_FUNCTION(get_class_methods)
12671267
if (Z_TYPE_P(klass) == IS_OBJECT) {
12681268
ce = Z_OBJCE_P(klass);
12691269
} else if (Z_TYPE_P(klass) == IS_STRING) {
1270-
ce = zend_lookup_class(Z_STR_P(klass));
1270+
ce = zend_lookup_class(Z_STR_P(klass));
12711271
}
12721272

12731273
if (!ce) {
@@ -1281,10 +1281,10 @@ ZEND_FUNCTION(get_class_methods)
12811281

12821282
if ((mptr->common.fn_flags & ZEND_ACC_PUBLIC)
12831283
|| (scope &&
1284-
(((mptr->common.fn_flags & ZEND_ACC_PROTECTED) &&
1285-
zend_check_protected(mptr->common.scope, scope))
1284+
(((mptr->common.fn_flags & ZEND_ACC_PROTECTED) &&
1285+
zend_check_protected(mptr->common.scope, scope))
12861286
|| ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) &&
1287-
scope == mptr->common.scope)))
1287+
scope == mptr->common.scope)))
12881288
) {
12891289
if (mptr->type == ZEND_USER_FUNCTION &&
12901290
(!mptr->op_array.refcount || *mptr->op_array.refcount > 1) &&
@@ -1398,114 +1398,63 @@ ZEND_FUNCTION(property_exists)
13981398
}
13991399
/* }}} */
14001400

1401-
/* {{{ proto bool class_exists(string classname [, bool autoload])
1402-
Checks if the class exists */
1403-
ZEND_FUNCTION(class_exists)
1401+
static inline void class_exists_impl(INTERNAL_FUNCTION_PARAMETERS, int flags, int skip_flags) /* {{{ */
14041402
{
1405-
zend_string *class_name;
1406-
zend_string *lc_name;
1403+
zend_string *name;
1404+
zend_string *lcname;
14071405
zend_class_entry *ce;
14081406
zend_bool autoload = 1;
14091407

14101408
ZEND_PARSE_PARAMETERS_START(1, 2)
1411-
Z_PARAM_STR(class_name)
1409+
Z_PARAM_STR(name)
14121410
Z_PARAM_OPTIONAL
14131411
Z_PARAM_BOOL(autoload)
14141412
ZEND_PARSE_PARAMETERS_END();
14151413

14161414
if (!autoload) {
1417-
if (ZSTR_VAL(class_name)[0] == '\\') {
1415+
if (ZSTR_VAL(name)[0] == '\\') {
14181416
/* Ignore leading "\" */
1419-
lc_name = zend_string_alloc(ZSTR_LEN(class_name) - 1, 0);
1420-
zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(class_name) + 1, ZSTR_LEN(class_name) - 1);
1417+
lcname = zend_string_alloc(ZSTR_LEN(name) - 1, 0);
1418+
zend_str_tolower_copy(ZSTR_VAL(lcname), ZSTR_VAL(name) + 1, ZSTR_LEN(name) - 1);
14211419
} else {
1422-
lc_name = zend_string_tolower(class_name);
1420+
lcname = zend_string_tolower(name);
14231421
}
14241422

1425-
ce = zend_hash_find_ptr(EG(class_table), lc_name);
1426-
zend_string_release_ex(lc_name, 0);
1423+
ce = zend_hash_find_ptr(EG(class_table), lcname);
1424+
zend_string_release_ex(lcname, 0);
14271425
} else {
1428-
ce = zend_lookup_class(class_name);
1426+
ce = zend_lookup_class(name);
14291427
}
14301428

14311429
if (ce) {
1432-
RETURN_BOOL((ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT)) == 0);
1430+
RETURN_BOOL((flags == 0 || (ce->ce_flags & flags)) && !(ce->ce_flags & skip_flags));
14331431
} else {
14341432
RETURN_FALSE;
14351433
}
14361434
}
1435+
/* {{{ */
1436+
1437+
/* {{{ proto bool class_exists(string classname [, bool autoload])
1438+
Checks if the class exists */
1439+
ZEND_FUNCTION(class_exists)
1440+
{
1441+
class_exists_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT);
1442+
}
14371443
/* }}} */
14381444

14391445
/* {{{ proto bool interface_exists(string classname [, bool autoload])
14401446
Checks if the class exists */
14411447
ZEND_FUNCTION(interface_exists)
14421448
{
1443-
zend_string *iface_name, *lc_name;
1444-
zend_class_entry *ce;
1445-
zend_bool autoload = 1;
1446-
1447-
ZEND_PARSE_PARAMETERS_START(1, 2)
1448-
Z_PARAM_STR(iface_name)
1449-
Z_PARAM_OPTIONAL
1450-
Z_PARAM_BOOL(autoload)
1451-
ZEND_PARSE_PARAMETERS_END();
1452-
1453-
if (!autoload) {
1454-
if (ZSTR_VAL(iface_name)[0] == '\\') {
1455-
/* Ignore leading "\" */
1456-
lc_name = zend_string_alloc(ZSTR_LEN(iface_name) - 1, 0);
1457-
zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(iface_name) + 1, ZSTR_LEN(iface_name) - 1);
1458-
} else {
1459-
lc_name = zend_string_tolower(iface_name);
1460-
}
1461-
ce = zend_hash_find_ptr(EG(class_table), lc_name);
1462-
zend_string_release_ex(lc_name, 0);
1463-
RETURN_BOOL(ce && ce->ce_flags & ZEND_ACC_INTERFACE);
1464-
}
1465-
1466-
ce = zend_lookup_class(iface_name);
1467-
if (ce) {
1468-
RETURN_BOOL((ce->ce_flags & ZEND_ACC_INTERFACE) > 0);
1469-
} else {
1470-
RETURN_FALSE;
1471-
}
1449+
class_exists_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_INTERFACE, 0);
14721450
}
14731451
/* }}} */
14741452

14751453
/* {{{ proto bool trait_exists(string traitname [, bool autoload])
14761454
Checks if the trait exists */
14771455
ZEND_FUNCTION(trait_exists)
14781456
{
1479-
zend_string *trait_name, *lc_name;
1480-
zend_class_entry *ce;
1481-
zend_bool autoload = 1;
1482-
1483-
ZEND_PARSE_PARAMETERS_START(1, 2)
1484-
Z_PARAM_STR(trait_name)
1485-
Z_PARAM_OPTIONAL
1486-
Z_PARAM_BOOL(autoload)
1487-
ZEND_PARSE_PARAMETERS_END();
1488-
1489-
if (!autoload) {
1490-
if (ZSTR_VAL(trait_name)[0] == '\\') {
1491-
/* Ignore leading "\" */
1492-
lc_name = zend_string_alloc(ZSTR_LEN(trait_name) - 1, 0);
1493-
zend_str_tolower_copy(ZSTR_VAL(lc_name), ZSTR_VAL(trait_name) + 1, ZSTR_LEN(trait_name) - 1);
1494-
} else {
1495-
lc_name = zend_string_tolower(trait_name);
1496-
}
1497-
1498-
ce = zend_hash_find_ptr(EG(class_table), lc_name);
1499-
zend_string_release_ex(lc_name, 0);
1500-
} else {
1501-
ce = zend_lookup_class(trait_name);
1502-
}
1503-
1504-
if (ce) {
1505-
RETURN_BOOL((ce->ce_flags & ZEND_ACC_TRAIT) != 0);
1506-
} else {
1507-
RETURN_FALSE;
1508-
}
1457+
class_exists_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_TRAIT, 0);
15091458
}
15101459
/* }}} */
15111460

@@ -1752,16 +1701,14 @@ ZEND_FUNCTION(restore_exception_handler)
17521701
static void copy_class_or_interface_name(zval *array, zend_string *key, zend_class_entry *ce) /* {{{ */
17531702
{
17541703
if ((ce->refcount == 1 && !(ce->ce_flags & ZEND_ACC_IMMUTABLE)) ||
1755-
same_name(key, ce->name)) {
1704+
same_name(key, ce->name)) {
17561705
key = ce->name;
17571706
}
17581707
add_next_index_str(array, zend_string_copy(key));
17591708
}
17601709
/* }}} */
17611710

1762-
/* {{{ proto array get_declared_traits()
1763-
Returns an array of all declared traits. */
1764-
ZEND_FUNCTION(get_declared_traits)
1711+
static inline void get_declared_class_impl(INTERNAL_FUNCTION_PARAMETERS, int flags, int skip_flags) /* {{{ */
17651712
{
17661713
zend_string *key;
17671714
zend_class_entry *ce;
@@ -1774,55 +1721,35 @@ ZEND_FUNCTION(get_declared_traits)
17741721
ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), key, ce) {
17751722
if (key
17761723
&& ZSTR_VAL(key)[0] != 0
1777-
&& (ce->ce_flags & ZEND_ACC_TRAIT)) {
1724+
&& (ce->ce_flags & flags)
1725+
&& !(ce->ce_flags & skip_flags)) {
17781726
copy_class_or_interface_name(return_value, key, ce);
17791727
}
17801728
} ZEND_HASH_FOREACH_END();
17811729
}
1730+
/* {{{ */
1731+
1732+
/* {{{ proto array get_declared_traits()
1733+
Returns an array of all declared traits. */
1734+
ZEND_FUNCTION(get_declared_traits)
1735+
{
1736+
get_declared_class_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_TRAIT, 0);
1737+
}
17821738
/* }}} */
17831739

17841740
/* {{{ proto array get_declared_classes()
17851741
Returns an array of all declared classes. */
17861742
ZEND_FUNCTION(get_declared_classes)
17871743
{
1788-
zend_string *key;
1789-
zend_class_entry *ce;
1790-
1791-
if (zend_parse_parameters_none() == FAILURE) {
1792-
return;
1793-
}
1794-
1795-
array_init(return_value);
1796-
ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), key, ce) {
1797-
if (key
1798-
&& ZSTR_VAL(key)[0] != 0
1799-
&& !(ce->ce_flags & (ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT))
1800-
&& (ce->ce_flags & ZEND_ACC_LINKED)) {
1801-
copy_class_or_interface_name(return_value, key, ce);
1802-
}
1803-
} ZEND_HASH_FOREACH_END();
1744+
get_declared_class_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_LINKED, ZEND_ACC_INTERFACE | ZEND_ACC_TRAIT);
18041745
}
18051746
/* }}} */
18061747

18071748
/* {{{ proto array get_declared_interfaces()
18081749
Returns an array of all declared interfaces. */
18091750
ZEND_FUNCTION(get_declared_interfaces)
18101751
{
1811-
zend_string *key;
1812-
zend_class_entry *ce;
1813-
1814-
if (zend_parse_parameters_none() == FAILURE) {
1815-
return;
1816-
}
1817-
1818-
array_init(return_value);
1819-
ZEND_HASH_FOREACH_STR_KEY_PTR(EG(class_table), key, ce) {
1820-
if (key
1821-
&& ZSTR_VAL(key)[0] != 0
1822-
&& (ce->ce_flags & ZEND_ACC_INTERFACE)) {
1823-
copy_class_or_interface_name(return_value, key, ce);
1824-
}
1825-
} ZEND_HASH_FOREACH_END();
1752+
get_declared_class_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, ZEND_ACC_INTERFACE, 0);
18261753
}
18271754
/* }}} */
18281755

@@ -2223,6 +2150,20 @@ void debug_print_backtrace_args(zval *arg_array) /* {{{ */
22232150
}
22242151
/* }}} */
22252152

2153+
static inline zend_bool skip_internal_handler(zend_execute_data *skip) /* {{{ */
2154+
{
2155+
return !(skip->func && ZEND_USER_CODE(skip->func->common.type))
2156+
&& skip->prev_execute_data
2157+
&& skip->prev_execute_data->func
2158+
&& ZEND_USER_CODE(skip->prev_execute_data->func->common.type)
2159+
&& skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL
2160+
&& skip->prev_execute_data->opline->opcode != ZEND_DO_ICALL
2161+
&& skip->prev_execute_data->opline->opcode != ZEND_DO_UCALL
2162+
&& skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME
2163+
&& skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL;
2164+
}
2165+
/* {{{ */
2166+
22262167
/* {{{ proto void debug_print_backtrace([int options[, int limit]]) */
22272168
ZEND_FUNCTION(debug_print_backtrace)
22282169
{
@@ -2261,15 +2202,7 @@ ZEND_FUNCTION(debug_print_backtrace)
22612202

22622203
skip = ptr;
22632204
/* skip internal handler */
2264-
if ((!skip->func || !ZEND_USER_CODE(skip->func->common.type)) &&
2265-
skip->prev_execute_data &&
2266-
skip->prev_execute_data->func &&
2267-
ZEND_USER_CODE(skip->prev_execute_data->func->common.type) &&
2268-
skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
2269-
skip->prev_execute_data->opline->opcode != ZEND_DO_ICALL &&
2270-
skip->prev_execute_data->opline->opcode != ZEND_DO_UCALL &&
2271-
skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
2272-
skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
2205+
if (skip_internal_handler(skip)) {
22732206
skip = skip->prev_execute_data;
22742207
}
22752208

@@ -2296,16 +2229,16 @@ ZEND_FUNCTION(debug_print_backtrace)
22962229
zend_string *zend_function_name;
22972230

22982231
func = call->func;
2299-
if (func->common.scope && func->common.scope->trait_aliases) {
2300-
zend_function_name = zend_resolve_method_name(object ? object->ce : func->common.scope, func);
2301-
} else {
2302-
zend_function_name = func->common.function_name;
2303-
}
2304-
if (zend_function_name != NULL) {
2305-
function_name = ZSTR_VAL(zend_function_name);
2306-
} else {
2307-
function_name = NULL;
2308-
}
2232+
if (func->common.scope && func->common.scope->trait_aliases) {
2233+
zend_function_name = zend_resolve_method_name(object ? object->ce : func->common.scope, func);
2234+
} else {
2235+
zend_function_name = func->common.function_name;
2236+
}
2237+
if (zend_function_name != NULL) {
2238+
function_name = ZSTR_VAL(zend_function_name);
2239+
} else {
2240+
function_name = NULL;
2241+
}
23092242
} else {
23102243
func = NULL;
23112244
function_name = NULL;
@@ -2397,7 +2330,7 @@ ZEND_FUNCTION(debug_print_backtrace)
23972330

23982331
while (prev) {
23992332
if (prev_call &&
2400-
prev_call->func &&
2333+
prev_call->func &&
24012334
!ZEND_USER_CODE(prev_call->func->common.type)) {
24022335
prev = NULL;
24032336
break;
@@ -2470,15 +2403,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
24702403

24712404
skip = ptr;
24722405
/* skip internal handler */
2473-
if ((!skip->func || !ZEND_USER_CODE(skip->func->common.type)) &&
2474-
skip->prev_execute_data &&
2475-
skip->prev_execute_data->func &&
2476-
ZEND_USER_CODE(skip->prev_execute_data->func->common.type) &&
2477-
skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL &&
2478-
skip->prev_execute_data->opline->opcode != ZEND_DO_ICALL &&
2479-
skip->prev_execute_data->opline->opcode != ZEND_DO_UCALL &&
2480-
skip->prev_execute_data->opline->opcode != ZEND_DO_FCALL_BY_NAME &&
2481-
skip->prev_execute_data->opline->opcode != ZEND_INCLUDE_OR_EVAL) {
2406+
if (skip_internal_handler(skip)) {
24822407
skip = skip->prev_execute_data;
24832408
}
24842409

@@ -2507,7 +2432,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
25072432

25082433
while (prev) {
25092434
if (prev_call &&
2510-
prev_call->func &&
2435+
prev_call->func &&
25112436
!ZEND_USER_CODE(prev_call->func->common.type) &&
25122437
!(prev_call->func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE)) {
25132438
break;
@@ -2531,7 +2456,7 @@ ZEND_API void zend_fetch_debug_backtrace(zval *return_value, int skip_last, int
25312456
if (call && call->func) {
25322457
func = call->func;
25332458
function_name = (func->common.scope &&
2534-
func->common.scope->trait_aliases) ?
2459+
func->common.scope->trait_aliases) ?
25352460
zend_resolve_method_name(
25362461
(object ? object->ce : func->common.scope), func) :
25372462
func->common.function_name;

0 commit comments

Comments
 (0)