7 #include "ext/standard/info.h"
8 #include "zend_constants.h"
9 #include "zend_operators.h"
18 # define PSI_ENGINE "jit"
23 # define PSI_ENGINE "ffi"
26 ZEND_DECLARE_MODULE_GLOBALS(psi
);
29 STD_PHP_INI_ENTRY("psi.engine", PSI_ENGINE
, PHP_INI_SYSTEM
, OnUpdateString
, engine
, zend_psi_globals
, psi_globals
)
30 STD_PHP_INI_ENTRY("psi.directory", "psi.d", PHP_INI_SYSTEM
, OnUpdateString
, directory
, zend_psi_globals
, psi_globals
)
33 static zend_object_handlers psi_object_handlers
;
34 static zend_class_entry
*psi_class_entry
;
36 zend_class_entry
*psi_object_get_class_entry()
38 return psi_class_entry
;
41 void psi_error_wrapper(void *context
, struct psi_token
*t
, int type
, const char *msg
, ...)
44 const char *fn
= NULL
;
48 if (PSI_DATA(context
)->flags
& PSI_PARSER_SILENT
) {
56 } else if (zend_is_executing()) {
57 fn
= zend_get_executed_filename();
58 ln
= zend_get_executed_lineno();
59 } else if (zend_is_compiling()) {
60 fn
= zend_get_compiled_filename()->val
;
61 ln
= zend_get_compiled_lineno();
65 psi_verror(type
, fn
, ln
, msg
, argv
);
69 void psi_error(int type
, const char *fn
, unsigned ln
, const char *msg
, ...)
74 psi_verror(type
, fn
, ln
, msg
, argv
);
78 void psi_verror(int type
, const char *fn
, unsigned ln
, const char *msg
, va_list argv
)
80 zend_error_cb(type
, fn
, ln
, msg
, argv
);
83 static void psi_object_free(zend_object
*o
)
85 psi_object
*obj
= PSI_OBJ(NULL
, o
);
88 /* FIXME: how about registering a destructor?
89 // free(obj->data); */
92 zend_object_std_dtor(o
);
95 static zend_object
*psi_object_init(zend_class_entry
*ce
)
97 psi_object
*o
= ecalloc(1, sizeof(*o
) + zend_object_properties_size(ce
));
99 zend_object_std_init(&o
->std
, ce
);
100 object_properties_init(&o
->std
, ce
);
101 o
->std
.handlers
= &psi_object_handlers
;
105 ZEND_BEGIN_ARG_INFO_EX(ai_psi_dump
, 0, 0, 0)
106 ZEND_ARG_INFO(0, stream
)
108 static PHP_FUNCTION(psi_dump
) {
111 int fd
= STDOUT_FILENO
;
113 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &r
)) {
117 php_stream_from_zval(s
, r
);
119 if (SUCCESS
!= php_stream_cast(s
, PHP_STREAM_AS_FD
| PHP_STREAM_CAST_INTERNAL
, (void **)&fd
, 1)) {
123 psi_context_dump(&PSI_G(context
), fd
);
126 ZEND_BEGIN_ARG_INFO_EX(ai_psi_validate
, 0, 0, 1)
127 ZEND_ARG_INFO(0, file
)
129 static PHP_FUNCTION(psi_validate
) {
133 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file
)) {
137 if (!psi_parser_init(&P
, file
->val
, psi_error_wrapper
, 0)) {
141 while (0 < psi_parser_scan(&P
)) {
142 psi_parser_parse(&P
, psi_token_alloc(&P
));
143 if (P
.num
== PSI_T_EOF
) {
147 psi_parser_parse(&P
, NULL
);
149 if (0 == psi_context_validate_data(NULL
, PSI_DATA(&P
)) && !P
.errors
) {
157 static PHP_MINIT_FUNCTION(psi
)
159 struct psi_context_ops
*ops
= NULL
;
160 zend_class_entry ce
= {0};
161 unsigned flags
= psi_check_env("PSI_DEBUG") ? PSI_PARSER_DEBUG
: (
162 psi_check_env("PSI_SILENT") ? PSI_PARSER_SILENT
: 0);
164 REGISTER_INI_ENTRIES();
166 INIT_NS_CLASS_ENTRY(ce
, "psi", "object", NULL
);
167 psi_class_entry
= zend_register_internal_class_ex(&ce
, NULL
);
168 psi_class_entry
->create_object
= psi_object_init
;
170 memcpy(&psi_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
171 psi_object_handlers
.offset
= XtOffsetOf(psi_object
, std
);
172 psi_object_handlers
.free_obj
= psi_object_free
;
173 psi_object_handlers
.clone_obj
= NULL
;
176 if (!strcasecmp(PSI_G(engine
), "jit")) {
177 ops
= psi_libjit_ops();
181 ops
= psi_libffi_ops();
185 php_error(E_WARNING
, "No PSI engine found");
189 psi_context_init(&PSI_G(context
), ops
, psi_error_wrapper
, flags
);
190 psi_context_build(&PSI_G(context
), PSI_G(directory
));
192 if (psi_check_env("PSI_DUMP")) {
193 psi_context_dump(&PSI_G(context
), STDOUT_FILENO
);
199 static PHP_MSHUTDOWN_FUNCTION(psi
)
201 psi_context_dtor(&PSI_G(context
));
203 UNREGISTER_INI_ENTRIES();
208 #if defined(COMPILE_DL_PSI) && defined(ZTS)
209 static PHP_RINIT_FUNCTION(psi
)
211 ZEND_TSRMLS_CACHE_UPDATE();
216 static PHP_MINFO_FUNCTION(psi
)
218 php_info_print_table_start();
219 php_info_print_table_header(2, "psi support", "enabled");
220 php_info_print_table_end();
222 DISPLAY_INI_ENTRIES();
225 static const zend_function_entry psi_functions
[] = {
226 PHP_FE(psi_dump
, ai_psi_dump
)
227 PHP_FE(psi_validate
, ai_psi_validate
)
231 zend_module_entry psi_module_entry
= {
232 STANDARD_MODULE_HEADER
,
237 #if defined(COMPILE_DL_PSI) && defined(ZTS)
238 PHP_RINIT(psi
), /* Replace with NULL if there's nothing to do at request start */
245 STANDARD_MODULE_PROPERTIES
248 #ifdef COMPILE_DL_PSI
250 ZEND_TSRMLS_CACHE_DEFINE();
260 * vim600: noet sw=4 ts=4 fdm=marker
261 * vim<600: noet sw=4 ts=4