flush
[m6w6/ext-psi] / src / module.c
1
2 #ifdef HAVE_CONFIG_H
3 #include "config.h"
4 #endif
5
6 #include <jit/jit.h>
7 #include <dirent.h>
8 #include <fnmatch.h>
9
10 #include "php.h"
11 #include "php_ini.h"
12 #include "ext/standard/info.h"
13 #include "php_scandir.h"
14
15 #include "php_psi.h"
16
17 #include "parser.h"
18 #include "validator.h"
19 #include "compiler.h"
20
21 ZEND_DECLARE_MODULE_GLOBALS(psi);
22
23 PHP_INI_BEGIN()
24 STD_PHP_INI_ENTRY("psi.directory", "psis", PHP_INI_ALL, OnUpdateString, directory, zend_psi_globals, psi_globals)
25 PHP_INI_END();
26
27 static int psi_select_dirent(const struct dirent *entry)
28 {
29 #ifndef FNM_CASEFOLD
30 #define FNM_CASEFOLD 0
31 #endif
32 return 0 == fnmatch("*.psi", entry->d_name, FNM_CASEFOLD);
33 }
34
35 PHP_MINIT_FUNCTION(psi)
36 {
37 jit_context_t ctx;
38 int i, n;
39 struct dirent **entries = NULL;
40
41 REGISTER_INI_ENTRIES();
42
43 jit_init();
44
45 if (!(ctx = jit_context_create())) {
46 zend_error(E_WARNING, "Could not initialize libjit!");
47 return FAILURE;
48 }
49
50 PSI_G(context) = ctx;
51
52 n = php_scandir(PSI_G(directory), &entries, psi_select_dirent, alphasort);
53 if (n < 0) {
54 php_error(E_WARNING, "Failed to scan PSI directory '%s'", PSI_G(directory));
55 } else for (i = 0; i < n; ++i) {
56 char psi[MAXPATHLEN];
57 PSI_Parser P;
58 PSI_Validator V;
59
60 if (MAXPATHLEN <= slprintf(psi, MAXPATHLEN, "%s/%s", PSI_G(directory), entries[i]->d_name)) {
61 php_error(E_WARNING, "Path to PSI file too long: %s/%s",
62 PSI_G(directory), entries[i]->d_name);
63 }
64 if (!PSI_ParserInit(&P, psi, 0)) {
65 php_error(E_WARNING, "Failed to init PSI parser (%s): %s",
66 psi, strerror(errno));
67 continue;
68 }
69
70 while (-1 != PSI_ParserScan(&P)) {
71 PSI_ParserParse(&P, PSI_TokenAlloc(&P));
72 };
73 PSI_ParserParse(&P, NULL);
74
75 if (!PSI_ValidatorInit(&V, &P)) {
76 php_error(E_WARNING, "Failed to init PSI validator");
77 break;
78 }
79 PSI_ParserDtor(&P);
80
81 if (PSI_ValidatorValidate(&V)) {
82 PSI_Compiler C;
83
84 jit_context_build_start(ctx);
85 if (PSI_CompilerInit(&C, &V, ctx)) {
86 zend_function_entry *closures = PSI_CompilerCompile(&C);
87
88 if (closures) {
89 if (SUCCESS != zend_register_functions(NULL, closures, NULL, MODULE_PERSISTENT)) {
90 fprintf(stderr, "Failed to register functions!\n");
91 }
92 }
93 //PSI_CompilerDtor(&C);
94 }
95 jit_context_build_end(ctx);
96 }
97 PSI_ValidatorDtor(&V);
98 }
99 if (entries) {
100 for (i = 0; i < n; ++i) {
101 free(entries[i]);
102 }
103 free(entries);
104 }
105 return SUCCESS;
106 }
107 PHP_MSHUTDOWN_FUNCTION(psi)
108 {
109 jit_context_t ctx = PSI_G(context);
110 jit_context_destroy(ctx);
111
112 UNREGISTER_INI_ENTRIES();
113
114 return SUCCESS;
115 }
116
117 /* Remove if there's nothing to do at request start */
118 /* {{{ PHP_RINIT_FUNCTION
119 */
120 PHP_RINIT_FUNCTION(psi)
121 {
122 #if defined(COMPILE_DL_PSI) && defined(ZTS)
123 ZEND_TSRMLS_CACHE_UPDATE();
124 #endif
125 return SUCCESS;
126 }
127 /* }}} */
128
129 /* Remove if there's nothing to do at request end */
130 /* {{{ PHP_RSHUTDOWN_FUNCTION
131 */
132 PHP_RSHUTDOWN_FUNCTION(psi)
133 {
134 return SUCCESS;
135 }
136 /* }}} */
137
138 PHP_MINFO_FUNCTION(psi)
139 {
140 php_info_print_table_start();
141 php_info_print_table_header(2, "psi support", "enabled");
142 php_info_print_table_end();
143
144 DISPLAY_INI_ENTRIES();
145 }
146 const zend_function_entry psi_functions[] = {
147 PHP_FE_END
148 };
149
150 zend_module_entry psi_module_entry = {
151 STANDARD_MODULE_HEADER,
152 "psi",
153 psi_functions,
154 PHP_MINIT(psi),
155 PHP_MSHUTDOWN(psi),
156 PHP_RINIT(psi), /* Replace with NULL if there's nothing to do at request start */
157 PHP_RSHUTDOWN(psi), /* Replace with NULL if there's nothing to do at request end */
158 PHP_MINFO(psi),
159 PHP_PSI_VERSION,
160 STANDARD_MODULE_PROPERTIES
161 };
162
163 #ifdef COMPILE_DL_PSI
164 #ifdef ZTS
165 ZEND_TSRMLS_CACHE_DEFINE();
166 #endif
167 ZEND_GET_MODULE(psi)
168 #endif
169
170 /*
171 * Local variables:
172 * tab-width: 4
173 * c-basic-offset: 4
174 * End:
175 * vim600: noet sw=4 ts=4 fdm=marker
176 * vim<600: noet sw=4 ts=4
177 */