Skip to content

Commit 373f5bb

Browse files
Initial zend_class_alias
Probably going to have a bunch of failures but I can't find any more locally
1 parent 8f3cdf6 commit 373f5bb

13 files changed

+226
-49
lines changed

Zend/zend_API.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "zend_enum.h"
3535
#include "zend_object_handlers.h"
3636
#include "zend_observer.h"
37+
#include "zend_class_alias.h"
3738

3839
#include <stdarg.h>
3940

@@ -2543,7 +2544,9 @@ ZEND_API void zend_collect_module_handlers(void) /* {{{ */
25432544
} ZEND_HASH_FOREACH_END();
25442545

25452546
/* Collect internal classes with static members */
2546-
ZEND_HASH_MAP_FOREACH_PTR(CG(class_table), ce) {
2547+
zval *ce_or_alias;
2548+
ZEND_HASH_MAP_FOREACH_VAL(CG(class_table), ce_or_alias) {
2549+
Z_CE_FROM_ZVAL_P(ce, ce_or_alias);
25472550
if (ce->type == ZEND_INTERNAL_CLASS &&
25482551
ce->default_static_members_count > 0) {
25492552
class_count++;
@@ -2557,7 +2560,8 @@ ZEND_API void zend_collect_module_handlers(void) /* {{{ */
25572560
class_cleanup_handlers[class_count] = NULL;
25582561

25592562
if (class_count) {
2560-
ZEND_HASH_MAP_FOREACH_PTR(CG(class_table), ce) {
2563+
ZEND_HASH_MAP_FOREACH_VAL(CG(class_table), ce_or_alias) {
2564+
Z_CE_FROM_ZVAL_P(ce, ce_or_alias);
25612565
if (ce->type == ZEND_INTERNAL_CLASS &&
25622566
ce->default_static_members_count > 0) {
25632567
class_cleanup_handlers[--class_count] = ce;
@@ -3282,8 +3286,9 @@ static void clean_module_classes(int module_number) /* {{{ */
32823286
{
32833287
/* Child classes may reuse structures from parent classes, so destroy in reverse order. */
32843288
Bucket *bucket;
3289+
zend_class_entry *ce;
32853290
ZEND_HASH_REVERSE_FOREACH_BUCKET(EG(class_table), bucket) {
3286-
zend_class_entry *ce = Z_CE(bucket->val);
3291+
Z_CE_FROM_ZVAL(ce, bucket->val);
32873292
if (ce->type == ZEND_INTERNAL_CLASS && ce->info.internal.module->module_number == module_number) {
32883293
zend_hash_del_bucket(EG(class_table), bucket);
32893294
}
@@ -3596,7 +3601,9 @@ ZEND_API zend_result zend_register_class_alias_ex(const char *name, size_t name_
35963601
* Instead of having to deal with differentiating between class types and lifetimes,
35973602
* we simply don't increase the refcount of a class entry for aliases.
35983603
*/
3599-
ZVAL_ALIAS_PTR(&zv, ce);
3604+
zend_class_alias *alias = zend_class_alias_init(ce);
3605+
3606+
ZVAL_ALIAS_PTR(&zv, alias);
36003607

36013608
ret = zend_hash_add(CG(class_table), lcname, &zv);
36023609
zend_string_release_ex(lcname, 0);
@@ -3723,11 +3730,12 @@ ZEND_API zend_result zend_disable_class(const char *class_name, size_t class_nam
37233730

37243731
key = zend_string_alloc(class_name_length, 0);
37253732
zend_str_tolower_copy(ZSTR_VAL(key), class_name, class_name_length);
3726-
disabled_class = zend_hash_find_ptr(CG(class_table), key);
3733+
zval *disabled_class_or_alias = zend_hash_find(CG(class_table), key);
37273734
zend_string_release_ex(key, 0);
3728-
if (!disabled_class) {
3735+
if (!disabled_class_or_alias) {
37293736
return FAILURE;
37303737
}
3738+
Z_CE_FROM_ZVAL_P(disabled_class, disabled_class_or_alias);
37313739

37323740
/* Will be reset by INIT_CLASS_ENTRY. */
37333741
free(disabled_class->interfaces);

Zend/zend_builtin_functions.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919

2020
#include "zend.h"
21+
#include "zend_class_alias.h"
2122
#include "zend_API.h"
2223
#include "zend_attributes.h"
2324
#include "zend_gc.h"
@@ -1398,7 +1399,7 @@ static inline void get_declared_class_impl(INTERNAL_FUNCTION_PARAMETERS, int fla
13981399
zend_hash_real_init_packed(Z_ARRVAL_P(return_value));
13991400
ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
14001401
ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(EG(class_table), key, zv) {
1401-
ce = Z_PTR_P(zv);
1402+
Z_CE_FROM_ZVAL_P(ce, zv);
14021403
if ((ce->ce_flags & (ZEND_ACC_LINKED|ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT)) == flags
14031404
&& key
14041405
&& ZSTR_VAL(key)[0] != 0) {

Zend/zend_class_alias.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| Zend Engine |
4+
+----------------------------------------------------------------------+
5+
| Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
6+
+----------------------------------------------------------------------+
7+
| This source file is subject to version 2.00 of the Zend license, |
8+
| that is bundled with this package in the file LICENSE, and is |
9+
| available through the world-wide-web at the following url: |
10+
| http://www.zend.com/license/2_00.txt. |
11+
| If you did not receive a copy of the Zend license and are unable to |
12+
| obtain it through the world-wide-web, please send a note to |
13+
| [email protected] so we can mail you a copy immediately. |
14+
+----------------------------------------------------------------------+
15+
| Authors: Daniel Scherzer <[email protected]> |
16+
+----------------------------------------------------------------------+
17+
*/
18+
19+
#include "zend_class_alias.h"
20+
21+
zend_class_alias * zend_class_alias_init(zend_class_entry *ce) {
22+
zend_class_alias *alias = malloc(sizeof(zend_class_alias));
23+
// refcount field is only there for compatibility with other structures
24+
GC_SET_REFCOUNT(alias, 1);
25+
26+
alias->ce = ce;
27+
28+
return alias;
29+
}

Zend/zend_class_alias.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| Zend Engine |
4+
+----------------------------------------------------------------------+
5+
| Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
6+
+----------------------------------------------------------------------+
7+
| This source file is subject to version 2.00 of the Zend license, |
8+
| that is bundled with this package in the file LICENSE, and is |
9+
| available through the world-wide-web at the following url: |
10+
| http://www.zend.com/license/2_00.txt. |
11+
| If you did not receive a copy of the Zend license and are unable to |
12+
| obtain it through the world-wide-web, please send a note to |
13+
| [email protected] so we can mail you a copy immediately. |
14+
+----------------------------------------------------------------------+
15+
| Authors: Daniel Scherzer <[email protected]> |
16+
+----------------------------------------------------------------------+
17+
*/
18+
19+
#ifndef ZEND_CLASS_ALIAS_H
20+
#define ZEND_CLASS_ALIAS_H
21+
22+
#include "zend_types.h"
23+
24+
struct _zend_class_alias {
25+
zend_refcounted_h gc;
26+
zend_class_entry *ce;
27+
};
28+
29+
typedef struct _zend_class_alias zend_class_alias;
30+
31+
#define Z_CE_FROM_ZVAL_P(_ce, _zv) do { \
32+
if (EXPECTED(Z_TYPE_P(_zv) == IS_PTR)) { \
33+
_ce = Z_PTR_P(_zv); \
34+
} else { \
35+
ZEND_ASSERT(Z_TYPE_P(_zv) == IS_ALIAS_PTR); \
36+
_ce = Z_CLASS_ALIAS_P(_zv)->ce; \
37+
} \
38+
} while (0) \
39+
40+
41+
#define Z_CE_FROM_ZVAL(_ce, _zv) do { \
42+
if (EXPECTED(Z_TYPE(_zv) == IS_PTR)) { \
43+
_ce = Z_PTR(_zv); \
44+
} else { \
45+
ZEND_ASSERT(Z_TYPE(_zv) == IS_ALIAS_PTR); \
46+
_ce = Z_CLASS_ALIAS(_zv)->ce; \
47+
} \
48+
} while (0) \
49+
50+
51+
zend_class_alias * zend_class_alias_init(zend_class_entry *ce);
52+
53+
#endif

Zend/zend_execute_API.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <signal.h>
2323

2424
#include "zend.h"
25+
#include "zend_class_alias.h"
2526
#include "zend_compile.h"
2627
#include "zend_execute.h"
2728
#include "zend_API.h"
@@ -327,7 +328,8 @@ ZEND_API void zend_shutdown_executor_values(bool fast_shutdown)
327328
}
328329
} ZEND_HASH_FOREACH_END();
329330
ZEND_HASH_MAP_REVERSE_FOREACH_VAL(EG(class_table), zv) {
330-
zend_class_entry *ce = Z_PTR_P(zv);
331+
zend_class_entry *ce;
332+
Z_CE_FROM_ZVAL_P(ce, zv);
331333

332334
if (ce->default_static_members_count) {
333335
zend_cleanup_internal_class_data(ce);
@@ -1201,7 +1203,7 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, zend_string *
12011203
if (!key) {
12021204
zend_string_release_ex(lc_name, 0);
12031205
}
1204-
ce = (zend_class_entry*)Z_PTR_P(zv);
1206+
Z_CE_FROM_ZVAL_P(ce, zv);
12051207
if (UNEXPECTED(!(ce->ce_flags & ZEND_ACC_LINKED))) {
12061208
if ((flags & ZEND_FETCH_CLASS_ALLOW_UNLINKED) ||
12071209
((flags & ZEND_FETCH_CLASS_ALLOW_NEARLY_LINKED) &&

Zend/zend_extensions.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
+----------------------------------------------------------------------+
1818
*/
1919

20+
#include "zend_class_alias.h"
2021
#include "zend_extensions.h"
2122
#include "zend_system_id.h"
2223

@@ -327,7 +328,9 @@ ZEND_API void zend_init_internal_run_time_cache(void) {
327328
if (rt_size) {
328329
size_t functions = zend_hash_num_elements(CG(function_table));
329330
zend_class_entry *ce;
330-
ZEND_HASH_MAP_FOREACH_PTR(CG(class_table), ce) {
331+
zval *ce_or_alias;
332+
ZEND_HASH_MAP_FOREACH_VAL(CG(class_table), ce_or_alias) {
333+
Z_CE_FROM_ZVAL_P(ce, ce_or_alias);
331334
functions += zend_hash_num_elements(&ce->function_table);
332335
} ZEND_HASH_FOREACH_END();
333336

@@ -344,7 +347,8 @@ ZEND_API void zend_init_internal_run_time_cache(void) {
344347
ptr += rt_size;
345348
}
346349
} ZEND_HASH_FOREACH_END();
347-
ZEND_HASH_MAP_FOREACH_PTR(CG(class_table), ce) {
350+
ZEND_HASH_MAP_FOREACH_VAL(CG(class_table), ce_or_alias) {
351+
Z_CE_FROM_ZVAL_P(ce, ce_or_alias);
348352
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, zif) {
349353
if (!ZEND_USER_CODE(zif->type) && ZEND_MAP_PTR_GET(zif->run_time_cache) == NULL) {
350354
ZEND_MAP_PTR_SET(zif->run_time_cache, (void *)ptr);

Zend/zend_observer.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "zend_observer.h"
2222

23+
#include "zend_class_alias.h"
2324
#include "zend_extensions.h"
2425
#include "zend_llist.h"
2526
#include "zend_vm.h"
@@ -89,7 +90,9 @@ ZEND_API void zend_observer_post_startup(void)
8990
++zif->T;
9091
} ZEND_HASH_FOREACH_END();
9192
zend_class_entry *ce;
92-
ZEND_HASH_MAP_FOREACH_PTR(CG(class_table), ce) {
93+
zval *ce_or_alias;
94+
ZEND_HASH_MAP_FOREACH_VAL(CG(class_table), ce_or_alias) {
95+
Z_CE_FROM_ZVAL_P(ce, ce_or_alias);
9396
ZEND_HASH_MAP_FOREACH_PTR(&ce->function_table, zif) {
9497
++zif->T;
9598
} ZEND_HASH_FOREACH_END();

Zend/zend_types.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ typedef struct _zend_resource zend_resource;
9999
typedef struct _zend_reference zend_reference;
100100
typedef struct _zend_ast_ref zend_ast_ref;
101101
typedef struct _zend_ast zend_ast;
102+
typedef struct _zend_class_alias zend_class_alias;
102103

103104
typedef int (*compare_func_t)(const void *, const void *);
104105
typedef void (*swap_func_t)(void *, void *);
@@ -346,6 +347,7 @@ typedef union _zend_value {
346347
void *ptr;
347348
zend_class_entry *ce;
348349
zend_function *func;
350+
zend_class_alias *class_alias;
349351
struct {
350352
uint32_t w1;
351353
uint32_t w2;
@@ -1065,6 +1067,9 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
10651067
#define Z_PTR(zval) (zval).value.ptr
10661068
#define Z_PTR_P(zval_p) Z_PTR(*(zval_p))
10671069

1070+
#define Z_CLASS_ALIAS(zval) (zval).value.class_alias
1071+
#define Z_CLASS_ALIAS_P(zval_p) Z_CLASS_ALIAS(*(zval_p))
1072+
10681073
#define ZVAL_UNDEF(z) do { \
10691074
Z_TYPE_INFO_P(z) = IS_UNDEF; \
10701075
} while (0)
@@ -1277,7 +1282,7 @@ static zend_always_inline uint32_t zval_gc_info(uint32_t gc_type_info) {
12771282
} while (0)
12781283

12791284
#define ZVAL_ALIAS_PTR(z, p) do { \
1280-
Z_PTR_P(z) = (p); \
1285+
Z_CLASS_ALIAS_P(z) = (p); \
12811286
Z_TYPE_INFO_P(z) = IS_ALIAS_PTR; \
12821287
} while (0)
12831288

configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1735,6 +1735,7 @@ PHP_ADD_SOURCES([Zend], m4_normalize([
17351735
zend_attributes.c
17361736
zend_builtin_functions.c
17371737
zend_call_stack.c
1738+
zend_class_alias.c
17381739
zend_closures.c
17391740
zend_compile.c
17401741
zend_constants.c

0 commit comments

Comments
 (0)