8 #include "ext/standard/info.h"
9 #include "zend_constants.h"
10 #include "zend_operators.h"
17 # define PSI_ENGINE "jit"
22 # define PSI_ENGINE "ffi"
25 ZEND_DECLARE_MODULE_GLOBALS(psi
);
28 STD_PHP_INI_ENTRY("psi.engine", PSI_ENGINE
, PHP_INI_SYSTEM
, OnUpdateString
, engine
, zend_psi_globals
, psi_globals
)
29 STD_PHP_INI_ENTRY("psi.directory", "psi.d", PHP_INI_SYSTEM
, OnUpdateString
, directory
, zend_psi_globals
, psi_globals
)
32 static zend_object_handlers psi_object_handlers
;
33 static zend_class_entry
*psi_class_entry
;
35 zend_class_entry
*psi_object_get_class_entry()
37 return psi_class_entry
;
40 void psi_error_wrapper(void *context
, PSI_Token
*t
, int type
, const char *msg
, ...)
43 const char *fn
= NULL
;
47 if (PSI_DATA(context
)->flags
& PSI_PARSER_SILENT
) {
55 } else if (zend_is_executing()) {
56 fn
= zend_get_executed_filename();
57 ln
= zend_get_executed_lineno();
58 } else if (zend_is_compiling()) {
59 fn
= zend_get_compiled_filename()->val
;
60 ln
= zend_get_compiled_lineno();
64 psi_verror(type
, fn
, ln
, msg
, argv
);
68 void psi_error(int type
, const char *fn
, unsigned ln
, const char *msg
, ...)
73 psi_verror(type
, fn
, ln
, msg
, argv
);
77 void psi_verror(int type
, const char *fn
, unsigned ln
, const char *msg
, va_list argv
)
79 zend_error_cb(type
, fn
, ln
, msg
, argv
);
82 static void psi_object_free(zend_object
*o
)
84 psi_object
*obj
= PSI_OBJ(NULL
, o
);
87 /* FIXME: how about registering a destructor?
88 // free(obj->data); */
91 zend_object_std_dtor(o
);
94 static zend_object
*psi_object_init(zend_class_entry
*ce
)
96 psi_object
*o
= ecalloc(1, sizeof(*o
) + zend_object_properties_size(ce
));
98 zend_object_std_init(&o
->std
, ce
);
99 object_properties_init(&o
->std
, ce
);
100 o
->std
.handlers
= &psi_object_handlers
;
104 ZEND_BEGIN_ARG_INFO_EX(ai_psi_dump
, 0, 0, 0)
105 ZEND_ARG_INFO(0, stream
)
107 static PHP_FUNCTION(psi_dump
) {
110 int fd
= STDOUT_FILENO
;
112 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &r
)) {
116 php_stream_from_zval(s
, r
);
118 if (SUCCESS
!= php_stream_cast(s
, PHP_STREAM_AS_FD
| PHP_STREAM_CAST_INTERNAL
, (void **)&fd
, 1)) {
122 PSI_ContextDump(&PSI_G(context
), fd
);
125 ZEND_BEGIN_ARG_INFO_EX(ai_psi_validate
, 0, 0, 1)
126 ZEND_ARG_INFO(0, file
)
128 static PHP_FUNCTION(psi_validate
) {
132 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file
)) {
136 if (!PSI_ParserInit(&P
, file
->val
, psi_error_wrapper
, 0)) {
140 while (0 < PSI_ParserScan(&P
)) {
141 PSI_ParserParse(&P
, PSI_TokenAlloc(&P
));
142 if (P
.num
== PSI_T_EOF
) {
146 PSI_ParserParse(&P
, NULL
);
148 if (0 == PSI_ContextValidateData(NULL
, PSI_DATA(&P
)) && !P
.errors
) {
156 static PHP_MINIT_FUNCTION(psi
)
158 PSI_ContextOps
*ops
= NULL
;
159 zend_class_entry ce
= {0};
160 unsigned flags
= psi_check_env("PSI_DEBUG") ? PSI_PARSER_DEBUG
: (
161 psi_check_env("PSI_SILENT") ? PSI_PARSER_SILENT
: 0);
163 REGISTER_INI_ENTRIES();
165 INIT_NS_CLASS_ENTRY(ce
, "psi", "object", NULL
);
166 psi_class_entry
= zend_register_internal_class_ex(&ce
, NULL
);
167 psi_class_entry
->create_object
= psi_object_init
;
169 memcpy(&psi_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
170 psi_object_handlers
.offset
= XtOffsetOf(psi_object
, std
);
171 psi_object_handlers
.free_obj
= psi_object_free
;
172 psi_object_handlers
.clone_obj
= NULL
;
175 if (!strcasecmp(PSI_G(engine
), "jit")) {
184 php_error(E_WARNING
, "No PSI engine found");
188 PSI_ContextInit(&PSI_G(context
), ops
, psi_error_wrapper
, flags
);
189 PSI_ContextBuild(&PSI_G(context
), PSI_G(directory
));
191 if (psi_check_env("PSI_DUMP")) {
192 PSI_ContextDump(&PSI_G(context
), STDOUT_FILENO
);
198 static PHP_MSHUTDOWN_FUNCTION(psi
)
200 PSI_ContextDtor(&PSI_G(context
));
202 UNREGISTER_INI_ENTRIES();
207 #if defined(COMPILE_DL_PSI) && defined(ZTS)
208 static PHP_RINIT_FUNCTION(psi
)
210 ZEND_TSRMLS_CACHE_UPDATE();
215 static PHP_MINFO_FUNCTION(psi
)
217 php_info_print_table_start();
218 php_info_print_table_header(2, "psi support", "enabled");
219 php_info_print_table_end();
221 DISPLAY_INI_ENTRIES();
224 static const zend_function_entry psi_functions
[] = {
225 PHP_FE(psi_dump
, ai_psi_dump
)
226 PHP_FE(psi_validate
, ai_psi_validate
)
230 zend_module_entry psi_module_entry
= {
231 STANDARD_MODULE_HEADER
,
236 #if defined(COMPILE_DL_PSI) && defined(ZTS)
237 PHP_RINIT(psi
), /* Replace with NULL if there's nothing to do at request start */
244 STANDARD_MODULE_PROPERTIES
247 #ifdef COMPILE_DL_PSI
249 ZEND_TSRMLS_CACHE_DEFINE();
259 * vim600: noet sw=4 ts=4 fdm=marker
260 * vim<600: noet sw=4 ts=4