Skip to content

Commit 8c37bb9

Browse files
committed
ext/spl: refactor reflection-like functions
Make the helpers private and remove a lot of unnecessary computation and code that was effectively dead.
1 parent 437dce7 commit 8c37bb9

File tree

3 files changed

+102
-130
lines changed

3 files changed

+102
-130
lines changed

ext/spl/php_spl.c

Lines changed: 102 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,43 @@ static zend_class_entry * spl_find_ce_by_name(zend_string *name, bool autoload)
6060
return ce;
6161
}
6262

63+
static void spl_add_class_name(HashTable *list, zend_string *name)
64+
{
65+
zval t;
66+
ZVAL_STR_COPY(&t, name);
67+
zend_hash_add(list, name, &t);
68+
}
69+
70+
static void spl_add_interfaces(HashTable *list, const zend_class_entry *pce)
71+
{
72+
if (pce->num_interfaces) {
73+
ZEND_ASSERT(pce->ce_flags & ZEND_ACC_LINKED);
74+
for (uint32_t num_interfaces = 0; num_interfaces < pce->num_interfaces; num_interfaces++) {
75+
spl_add_class_name(list, pce->interfaces[num_interfaces]->name);
76+
}
77+
}
78+
}
79+
80+
static void spl_add_traits(HashTable *list, const zend_class_entry *pce)
81+
{
82+
for (uint32_t num_traits = 0; num_traits < pce->num_traits; num_traits++) {
83+
spl_add_class_name(list, pce->trait_names[num_traits].name);
84+
}
85+
}
86+
87+
static void spl_add_classes(HashTable *list, const zend_class_entry *pce, bool only_classes, bool only_interfaces)
88+
{
89+
ZEND_ASSERT(pce);
90+
ZEND_ASSERT(!(only_classes && only_interfaces) && "Cannot have both only classes and only interfaces be enabled");
91+
if (
92+
(only_classes && (pce->ce_flags & ZEND_ACC_INTERFACE) == ZEND_ACC_INTERFACE)
93+
|| (only_interfaces && (pce->ce_flags & ZEND_ACC_INTERFACE) == 0)
94+
) {
95+
return;
96+
}
97+
spl_add_class_name(list, pce->name);
98+
}
99+
63100
/* {{{ Return an array containing the names of all parent classes */
64101
PHP_FUNCTION(class_parents)
65102
{
@@ -88,7 +125,7 @@ PHP_FUNCTION(class_parents)
88125
array_init(return_value);
89126
const zend_class_entry *parent_class = ce->parent;
90127
while (parent_class) {
91-
spl_add_class_name(return_value, parent_class, 0, 0);
128+
spl_add_class_name(Z_ARR_P(return_value), parent_class->name);
92129
parent_class = parent_class->parent;
93130
}
94131
}
@@ -119,7 +156,7 @@ PHP_FUNCTION(class_implements)
119156
}
120157

121158
array_init(return_value);
122-
spl_add_interfaces(return_value, ce, 1, ZEND_ACC_INTERFACE);
159+
spl_add_interfaces(Z_ARR_P(return_value), ce);
123160
}
124161
/* }}} */
125162

@@ -148,69 +185,69 @@ PHP_FUNCTION(class_uses)
148185
}
149186

150187
array_init(return_value);
151-
spl_add_traits(return_value, ce, 1, ZEND_ACC_TRAIT);
188+
spl_add_traits(Z_ARR_P(return_value), ce);
152189
}
153190
/* }}} */
154191

155-
#define SPL_ADD_CLASS(class_name, z_list, sub, allow, ce_flags) \
156-
spl_add_classes(spl_ce_ ## class_name, z_list, sub, allow, ce_flags)
157-
158-
#define SPL_LIST_CLASSES(z_list, sub, allow, ce_flags) \
159-
SPL_ADD_CLASS(AppendIterator, z_list, sub, allow, ce_flags); \
160-
SPL_ADD_CLASS(ArrayIterator, z_list, sub, allow, ce_flags); \
161-
SPL_ADD_CLASS(ArrayObject, z_list, sub, allow, ce_flags); \
162-
SPL_ADD_CLASS(BadFunctionCallException, z_list, sub, allow, ce_flags); \
163-
SPL_ADD_CLASS(BadMethodCallException, z_list, sub, allow, ce_flags); \
164-
SPL_ADD_CLASS(CachingIterator, z_list, sub, allow, ce_flags); \
165-
SPL_ADD_CLASS(CallbackFilterIterator, z_list, sub, allow, ce_flags); \
166-
SPL_ADD_CLASS(DirectoryIterator, z_list, sub, allow, ce_flags); \
167-
SPL_ADD_CLASS(DomainException, z_list, sub, allow, ce_flags); \
168-
SPL_ADD_CLASS(EmptyIterator, z_list, sub, allow, ce_flags); \
169-
SPL_ADD_CLASS(FilesystemIterator, z_list, sub, allow, ce_flags); \
170-
SPL_ADD_CLASS(FilterIterator, z_list, sub, allow, ce_flags); \
171-
SPL_ADD_CLASS(GlobIterator, z_list, sub, allow, ce_flags); \
172-
SPL_ADD_CLASS(InfiniteIterator, z_list, sub, allow, ce_flags); \
173-
SPL_ADD_CLASS(InvalidArgumentException, z_list, sub, allow, ce_flags); \
174-
SPL_ADD_CLASS(IteratorIterator, z_list, sub, allow, ce_flags); \
175-
SPL_ADD_CLASS(LengthException, z_list, sub, allow, ce_flags); \
176-
SPL_ADD_CLASS(LimitIterator, z_list, sub, allow, ce_flags); \
177-
SPL_ADD_CLASS(LogicException, z_list, sub, allow, ce_flags); \
178-
SPL_ADD_CLASS(MultipleIterator, z_list, sub, allow, ce_flags); \
179-
SPL_ADD_CLASS(NoRewindIterator, z_list, sub, allow, ce_flags); \
180-
SPL_ADD_CLASS(OuterIterator, z_list, sub, allow, ce_flags); \
181-
SPL_ADD_CLASS(OutOfBoundsException, z_list, sub, allow, ce_flags); \
182-
SPL_ADD_CLASS(OutOfRangeException, z_list, sub, allow, ce_flags); \
183-
SPL_ADD_CLASS(OverflowException, z_list, sub, allow, ce_flags); \
184-
SPL_ADD_CLASS(ParentIterator, z_list, sub, allow, ce_flags); \
185-
SPL_ADD_CLASS(RangeException, z_list, sub, allow, ce_flags); \
186-
SPL_ADD_CLASS(RecursiveArrayIterator, z_list, sub, allow, ce_flags); \
187-
SPL_ADD_CLASS(RecursiveCachingIterator, z_list, sub, allow, ce_flags); \
188-
SPL_ADD_CLASS(RecursiveCallbackFilterIterator, z_list, sub, allow, ce_flags); \
189-
SPL_ADD_CLASS(RecursiveDirectoryIterator, z_list, sub, allow, ce_flags); \
190-
SPL_ADD_CLASS(RecursiveFilterIterator, z_list, sub, allow, ce_flags); \
191-
SPL_ADD_CLASS(RecursiveIterator, z_list, sub, allow, ce_flags); \
192-
SPL_ADD_CLASS(RecursiveIteratorIterator, z_list, sub, allow, ce_flags); \
193-
SPL_ADD_CLASS(RecursiveRegexIterator, z_list, sub, allow, ce_flags); \
194-
SPL_ADD_CLASS(RecursiveTreeIterator, z_list, sub, allow, ce_flags); \
195-
SPL_ADD_CLASS(RegexIterator, z_list, sub, allow, ce_flags); \
196-
SPL_ADD_CLASS(RuntimeException, z_list, sub, allow, ce_flags); \
197-
SPL_ADD_CLASS(SeekableIterator, z_list, sub, allow, ce_flags); \
198-
SPL_ADD_CLASS(SplDoublyLinkedList, z_list, sub, allow, ce_flags); \
199-
SPL_ADD_CLASS(SplFileInfo, z_list, sub, allow, ce_flags); \
200-
SPL_ADD_CLASS(SplFileObject, z_list, sub, allow, ce_flags); \
201-
SPL_ADD_CLASS(SplFixedArray, z_list, sub, allow, ce_flags); \
202-
SPL_ADD_CLASS(SplHeap, z_list, sub, allow, ce_flags); \
203-
SPL_ADD_CLASS(SplMinHeap, z_list, sub, allow, ce_flags); \
204-
SPL_ADD_CLASS(SplMaxHeap, z_list, sub, allow, ce_flags); \
205-
SPL_ADD_CLASS(SplObjectStorage, z_list, sub, allow, ce_flags); \
206-
SPL_ADD_CLASS(SplObserver, z_list, sub, allow, ce_flags); \
207-
SPL_ADD_CLASS(SplPriorityQueue, z_list, sub, allow, ce_flags); \
208-
SPL_ADD_CLASS(SplQueue, z_list, sub, allow, ce_flags); \
209-
SPL_ADD_CLASS(SplStack, z_list, sub, allow, ce_flags); \
210-
SPL_ADD_CLASS(SplSubject, z_list, sub, allow, ce_flags); \
211-
SPL_ADD_CLASS(SplTempFileObject, z_list, sub, allow, ce_flags); \
212-
SPL_ADD_CLASS(UnderflowException, z_list, sub, allow, ce_flags); \
213-
SPL_ADD_CLASS(UnexpectedValueException, z_list, sub, allow, ce_flags); \
192+
#define SPL_ADD_CLASS(class_name, z_list, only_classes, only_interfaces) \
193+
spl_add_classes(Z_ARR_P(z_list), spl_ce_ ## class_name, only_classes, only_interfaces)
194+
195+
#define SPL_LIST_CLASSES(z_list, only_classes, only_interfaces) \
196+
SPL_ADD_CLASS(AppendIterator, z_list, only_classes, only_interfaces); \
197+
SPL_ADD_CLASS(ArrayIterator, z_list, only_classes, only_interfaces); \
198+
SPL_ADD_CLASS(ArrayObject, z_list, only_classes, only_interfaces); \
199+
SPL_ADD_CLASS(BadFunctionCallException, z_list, only_classes, only_interfaces); \
200+
SPL_ADD_CLASS(BadMethodCallException, z_list, only_classes, only_interfaces); \
201+
SPL_ADD_CLASS(CachingIterator, z_list, only_classes, only_interfaces); \
202+
SPL_ADD_CLASS(CallbackFilterIterator, z_list, only_classes, only_interfaces); \
203+
SPL_ADD_CLASS(DirectoryIterator, z_list, only_classes, only_interfaces); \
204+
SPL_ADD_CLASS(DomainException, z_list, only_classes, only_interfaces); \
205+
SPL_ADD_CLASS(EmptyIterator, z_list, only_classes, only_interfaces); \
206+
SPL_ADD_CLASS(FilesystemIterator, z_list, only_classes, only_interfaces); \
207+
SPL_ADD_CLASS(FilterIterator, z_list, only_classes, only_interfaces); \
208+
SPL_ADD_CLASS(GlobIterator, z_list, only_classes, only_interfaces); \
209+
SPL_ADD_CLASS(InfiniteIterator, z_list, only_classes, only_interfaces); \
210+
SPL_ADD_CLASS(InvalidArgumentException, z_list, only_classes, only_interfaces); \
211+
SPL_ADD_CLASS(IteratorIterator, z_list, only_classes, only_interfaces); \
212+
SPL_ADD_CLASS(LengthException, z_list, only_classes, only_interfaces); \
213+
SPL_ADD_CLASS(LimitIterator, z_list, only_classes, only_interfaces); \
214+
SPL_ADD_CLASS(LogicException, z_list, only_classes, only_interfaces); \
215+
SPL_ADD_CLASS(MultipleIterator, z_list, only_classes, only_interfaces); \
216+
SPL_ADD_CLASS(NoRewindIterator, z_list, only_classes, only_interfaces); \
217+
SPL_ADD_CLASS(OuterIterator, z_list, only_classes, only_interfaces); \
218+
SPL_ADD_CLASS(OutOfBoundsException, z_list, only_classes, only_interfaces); \
219+
SPL_ADD_CLASS(OutOfRangeException, z_list, only_classes, only_interfaces); \
220+
SPL_ADD_CLASS(OverflowException, z_list, only_classes, only_interfaces); \
221+
SPL_ADD_CLASS(ParentIterator, z_list, only_classes, only_interfaces); \
222+
SPL_ADD_CLASS(RangeException, z_list, only_classes, only_interfaces); \
223+
SPL_ADD_CLASS(RecursiveArrayIterator, z_list, only_classes, only_interfaces); \
224+
SPL_ADD_CLASS(RecursiveCachingIterator, z_list, only_classes, only_interfaces); \
225+
SPL_ADD_CLASS(RecursiveCallbackFilterIterator, z_list, only_classes, only_interfaces); \
226+
SPL_ADD_CLASS(RecursiveDirectoryIterator, z_list, only_classes, only_interfaces); \
227+
SPL_ADD_CLASS(RecursiveFilterIterator, z_list, only_classes, only_interfaces); \
228+
SPL_ADD_CLASS(RecursiveIterator, z_list, only_classes, only_interfaces); \
229+
SPL_ADD_CLASS(RecursiveIteratorIterator, z_list, only_classes, only_interfaces); \
230+
SPL_ADD_CLASS(RecursiveRegexIterator, z_list, only_classes, only_interfaces); \
231+
SPL_ADD_CLASS(RecursiveTreeIterator, z_list, only_classes, only_interfaces); \
232+
SPL_ADD_CLASS(RegexIterator, z_list, only_classes, only_interfaces); \
233+
SPL_ADD_CLASS(RuntimeException, z_list, only_classes, only_interfaces); \
234+
SPL_ADD_CLASS(SeekableIterator, z_list, only_classes, only_interfaces); \
235+
SPL_ADD_CLASS(SplDoublyLinkedList, z_list, only_classes, only_interfaces); \
236+
SPL_ADD_CLASS(SplFileInfo, z_list, only_classes, only_interfaces); \
237+
SPL_ADD_CLASS(SplFileObject, z_list, only_classes, only_interfaces); \
238+
SPL_ADD_CLASS(SplFixedArray, z_list, only_classes, only_interfaces); \
239+
SPL_ADD_CLASS(SplHeap, z_list, only_classes, only_interfaces); \
240+
SPL_ADD_CLASS(SplMinHeap, z_list, only_classes, only_interfaces); \
241+
SPL_ADD_CLASS(SplMaxHeap, z_list, only_classes, only_interfaces); \
242+
SPL_ADD_CLASS(SplObjectStorage, z_list, only_classes, only_interfaces); \
243+
SPL_ADD_CLASS(SplObserver, z_list, only_classes, only_interfaces); \
244+
SPL_ADD_CLASS(SplPriorityQueue, z_list, only_classes, only_interfaces); \
245+
SPL_ADD_CLASS(SplQueue, z_list, only_classes, only_interfaces); \
246+
SPL_ADD_CLASS(SplStack, z_list, only_classes, only_interfaces); \
247+
SPL_ADD_CLASS(SplSubject, z_list, only_classes, only_interfaces); \
248+
SPL_ADD_CLASS(SplTempFileObject, z_list, only_classes, only_interfaces); \
249+
SPL_ADD_CLASS(UnderflowException, z_list, only_classes, only_interfaces); \
250+
SPL_ADD_CLASS(UnexpectedValueException, z_list, only_classes, only_interfaces); \
214251

215252
/* {{{ Return an array containing the names of all classes and interfaces defined in SPL */
216253
PHP_FUNCTION(spl_classes)
@@ -219,7 +256,7 @@ PHP_FUNCTION(spl_classes)
219256

220257
array_init(return_value);
221258

222-
SPL_LIST_CLASSES(return_value, 0, 0, 0)
259+
SPL_LIST_CLASSES(return_value, false, false)
223260
}
224261
/* }}} */
225262

@@ -486,7 +523,7 @@ PHP_MINFO_FUNCTION(spl)
486523
php_info_print_table_row(2, "SPL support", "enabled");
487524

488525
array_init(&list);
489-
SPL_LIST_CLASSES(&list, 0, 1, ZEND_ACC_INTERFACE)
526+
SPL_LIST_CLASSES(&list, false, true)
490527
strg = estrdup("");
491528
ZEND_HASH_MAP_FOREACH_VAL(Z_ARRVAL_P(&list), zv) {
492529
spl_build_class_list_string(zv, &strg);
@@ -496,7 +533,7 @@ PHP_MINFO_FUNCTION(spl)
496533
efree(strg);
497534

498535
array_init(&list);
499-
SPL_LIST_CLASSES(&list, 0, -1, ZEND_ACC_INTERFACE)
536+
SPL_LIST_CLASSES(&list, true, false)
500537
strg = estrdup("");
501538
ZEND_HASH_MAP_FOREACH_VAL(Z_ARRVAL_P(&list), zv) {
502539
spl_build_class_list_string(zv, &strg);

ext/spl/spl_functions.c

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -20,61 +20,6 @@
2020

2121
#include "php.h"
2222

23-
/* {{{ spl_add_class_name */
24-
void spl_add_class_name(zval *list, const zend_class_entry *pce, int allow, int ce_flags)
25-
{
26-
if (!allow || (allow > 0 && (pce->ce_flags & ce_flags)) || (allow < 0 && !(pce->ce_flags & ce_flags))) {
27-
const zval *tmp = zend_hash_find(Z_ARRVAL_P(list), pce->name);
28-
29-
if (tmp == NULL) {
30-
zval t;
31-
ZVAL_STR_COPY(&t, pce->name);
32-
zend_hash_add(Z_ARRVAL_P(list), pce->name, &t);
33-
}
34-
}
35-
}
36-
/* }}} */
37-
38-
/* {{{ spl_add_interfaces */
39-
void spl_add_interfaces(zval *list, const zend_class_entry *pce, int allow, int ce_flags)
40-
{
41-
if (pce->num_interfaces) {
42-
ZEND_ASSERT(pce->ce_flags & ZEND_ACC_LINKED);
43-
for (uint32_t num_interfaces = 0; num_interfaces < pce->num_interfaces; num_interfaces++) {
44-
spl_add_class_name(list, pce->interfaces[num_interfaces], allow, ce_flags);
45-
}
46-
}
47-
}
48-
/* }}} */
49-
50-
/* {{{ spl_add_traits */
51-
void spl_add_traits(zval *list, const zend_class_entry *pce, int allow, int ce_flags)
52-
{
53-
for (uint32_t num_traits = 0; num_traits < pce->num_traits; num_traits++) {
54-
const zend_class_entry *trait = zend_fetch_class_by_name(pce->trait_names[num_traits].name,
55-
pce->trait_names[num_traits].lc_name, ZEND_FETCH_CLASS_TRAIT);
56-
ZEND_ASSERT(trait);
57-
spl_add_class_name(list, trait, allow, ce_flags);
58-
}
59-
}
60-
/* }}} */
61-
62-
63-
/* {{{ spl_add_classes */
64-
void spl_add_classes(const zend_class_entry *pce, zval *list, bool sub, int allow, int ce_flags)
65-
{
66-
ZEND_ASSERT(pce);
67-
spl_add_class_name(list, pce, allow, ce_flags);
68-
if (sub) {
69-
spl_add_interfaces(list, pce, allow, ce_flags);
70-
while (pce->parent) {
71-
pce = pce->parent;
72-
spl_add_classes(pce, list, sub, allow, ce_flags);
73-
}
74-
}
75-
}
76-
/* }}} */
77-
7823
void spl_set_private_debug_info_property(
7924
const zend_class_entry *ce,
8025
const char *property,

ext/spl/spl_functions.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,6 @@
1919

2020
#include "php.h"
2121

22-
/* sub: whether to allow subclasses/interfaces
23-
allow = 0: allow all classes and interfaces
24-
allow > 0: allow all that match and mask ce_flags
25-
allow < 0: disallow all that match and mask ce_flags
26-
*/
27-
void spl_add_class_name(zval * list, const zend_class_entry *pce, int allow, int ce_flags);
28-
void spl_add_interfaces(zval * list, const zend_class_entry *pce, int allow, int ce_flags);
29-
void spl_add_traits(zval * list, const zend_class_entry *pce, int allow, int ce_flags);
30-
void spl_add_classes(const zend_class_entry *pce, zval *list, bool sub, int allow, int ce_flags);
31-
3222
void spl_set_private_debug_info_property(const zend_class_entry *ce, const char *property, size_t property_len, HashTable *debug_info, zval *value);
3323

3424
#endif /* PHP_FUNCTIONS_H */

0 commit comments

Comments
 (0)