Skip to content

Commit 5f0f77d

Browse files
committed
namespaces: add support
This adds a new EG to support the addition of using namespaces as a class's lexical scope
1 parent 67f8bea commit 5f0f77d

File tree

6 files changed

+128
-1
lines changed

6 files changed

+128
-1
lines changed

Zend/zend_compile.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,6 +1061,7 @@ ZEND_API zend_string *zend_type_to_string(zend_type type);
10611061

10621062
#define ZEND_INTERNAL_CLASS 1
10631063
#define ZEND_USER_CLASS 2
1064+
#define ZEND_NAMESPACE_CLASS 3
10641065

10651066
#define ZEND_EVAL (1<<0)
10661067
#define ZEND_INCLUDE (1<<1)

Zend/zend_globals.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ struct _zend_executor_globals {
191191
HashTable *function_table; /* function symbol table */
192192
HashTable *class_table; /* class table */
193193
HashTable *zend_constants; /* constants table */
194+
HashTable *namespaces; /* namespace table */
195+
zend_class_entry *global_namespace;
194196

195197
zval *vm_stack_top;
196198
zval *vm_stack_end;

Zend/zend_namespaces.c

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
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: Rob Landers <[email protected]> |
16+
| |
17+
+----------------------------------------------------------------------+
18+
*/
19+
20+
#include "zend_namespaces.h"
21+
#include "zend_API.h"
22+
#include "zend_hash.h"
23+
24+
zend_class_entry *create_namespace(zend_string *name) {
25+
zend_class_entry *ns = pemalloc(sizeof(zend_class_entry *), 0);
26+
zend_initialize_class_data(ns, 1);
27+
ns->type = ZEND_NAMESPACE_CLASS;
28+
ns->ce_flags |= ZEND_ACC_UNINSTANTIABLE;
29+
ns->name = zend_string_copy(name);
30+
31+
return ns;
32+
}
33+
34+
static zend_class_entry *insert_namespace(const zend_string *name) {
35+
zend_class_entry *parent_ns = EG(global_namespace);
36+
zend_class_entry *ns = parent_ns;
37+
const char *start = ZSTR_VAL(name);
38+
const char *end = start + ZSTR_LEN(name);
39+
const char *pos = start;
40+
size_t len = 0;
41+
42+
while (pos <= end) {
43+
if (pos == end || *pos == '\\') {
44+
len = pos - start;
45+
zend_string *needle = zend_string_init(ZSTR_VAL(name), len, 0);
46+
47+
ns = zend_hash_find_ptr(EG(namespaces), needle);
48+
49+
if (!ns) {
50+
zend_string *interned_name = zend_new_interned_string(needle);
51+
ns = create_namespace(interned_name);
52+
ns->lexical_scope = parent_ns;
53+
zend_hash_add_ptr(EG(namespaces), interned_name, ns);
54+
}
55+
zend_string_release(needle);
56+
57+
parent_ns = ns;
58+
}
59+
pos ++;
60+
}
61+
62+
return ns;
63+
}
64+
65+
zend_class_entry *zend_resolve_namespace(zend_string *name) {
66+
if (EG(global_namespace) == NULL) {
67+
EG(global_namespace) = create_namespace(zend_empty_string);
68+
EG(global_namespace)->lexical_scope = NULL;
69+
zend_hash_init(EG(namespaces), 8, NULL, ZEND_CLASS_DTOR, 0);
70+
zend_hash_add_ptr(EG(namespaces), zend_empty_string, EG(global_namespace));
71+
}
72+
73+
if (name == NULL || ZSTR_LEN(name) == 0) {
74+
return EG(global_namespace);
75+
}
76+
77+
zend_string *lc_name = zend_string_tolower(name);
78+
zend_class_entry *ns = zend_hash_find_ptr(EG(namespaces), lc_name);
79+
80+
if (!ns) {
81+
ns = insert_namespace(lc_name);
82+
}
83+
84+
zend_string_release(lc_name);
85+
86+
return ns;
87+
}
88+
89+
zend_class_entry *zend_lookup_namespace(zend_string *name) {
90+
zend_string *lc_name = zend_string_tolower(name);
91+
zend_class_entry *ns = zend_hash_find_ptr(EG(namespaces), lc_name);
92+
zend_string_release(lc_name);
93+
94+
return ns;
95+
}

Zend/zend_namespaces.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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: Rob Landers <[email protected]> |
16+
| |
17+
+----------------------------------------------------------------------+
18+
*/
19+
20+
#ifndef ZEND_NAMESPACES_H
21+
#define ZEND_NAMESPACES_H
22+
23+
#include "zend_compile.h"
24+
25+
ZEND_API zend_class_entry *zend_resolve_namespace(zend_string *name);
26+
ZEND_API zend_class_entry *zend_lookup_namespace(zend_string *name);
27+
28+
#endif //ZEND_NAMESPACES_H

configure.ac

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,6 +1757,7 @@ PHP_ADD_SOURCES([Zend], m4_normalize([
17571757
zend_opcode.c
17581758
zend_operators.c
17591759
zend_property_hooks.c
1760+
zend_namespaces.c
17601761
zend_ptr_stack.c
17611762
zend_signal.c
17621763
zend_smart_str.c

win32/build/config.w32

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \
240240
zend_default_classes.c zend_execute.c zend_strtod.c zend_gc.c zend_closures.c zend_weakrefs.c \
241241
zend_float.c zend_string.c zend_generators.c zend_virtual_cwd.c zend_ast.c \
242242
zend_inheritance.c zend_smart_str.c zend_cpuinfo.c zend_observer.c zend_system_id.c \
243-
zend_enum.c zend_fibers.c zend_atomic.c zend_hrtime.c zend_frameless_function.c zend_property_hooks.c \
243+
zend_enum.c zend_fibers.c zend_atomic.c zend_hrtime.c zend_frameless_function.c zend_property_hooks.c zend_namespaces.c \
244244
zend_lazy_objects.c");
245245
ADD_SOURCES("Zend\\Optimizer", "zend_optimizer.c pass1.c pass3.c optimize_func_calls.c block_pass.c optimize_temp_vars_5.c nop_removal.c compact_literals.c zend_cfg.c zend_dfg.c dfa_pass.c zend_ssa.c zend_inference.c zend_func_info.c zend_call_graph.c zend_dump.c escape_analysis.c compact_vars.c dce.c sccp.c scdf.c");
246246

0 commit comments

Comments
 (0)