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(PSI_Token
*t
, int type
, const char *msg
, ...)
43 const char *fn
= NULL
;
49 } else if (zend_is_executing()) {
50 fn
= zend_get_executed_filename();
51 ln
= zend_get_executed_lineno();
52 } else if (zend_is_compiling()) {
53 fn
= zend_get_compiled_filename()->val
;
54 ln
= zend_get_compiled_lineno();
58 psi_verror(type
, fn
, ln
, msg
, argv
);
62 void psi_error(int type
, const char *fn
, unsigned ln
, const char *msg
, ...)
67 psi_verror(type
, fn
, ln
, msg
, argv
);
71 void psi_verror(int type
, const char *fn
, unsigned ln
, const char *msg
, va_list argv
)
73 zend_error_cb(type
, fn
, ln
, msg
, argv
);
76 static void psi_object_free(zend_object
*o
)
78 psi_object
*obj
= PSI_OBJ(NULL
, o
);
81 /* FIXME: how about registering a destructor?
82 // free(obj->data); */
85 zend_object_std_dtor(o
);
88 static zend_object
*psi_object_init(zend_class_entry
*ce
)
90 psi_object
*o
= ecalloc(1, sizeof(*o
) + zend_object_properties_size(ce
));
92 zend_object_std_init(&o
->std
, ce
);
93 object_properties_init(&o
->std
, ce
);
94 o
->std
.handlers
= &psi_object_handlers
;
98 ZEND_BEGIN_ARG_INFO_EX(ai_psi_dump
, 0, 0, 0)
99 ZEND_ARG_INFO(0, stream
)
101 static PHP_FUNCTION(psi_dump
) {
104 int fd
= STDOUT_FILENO
;
106 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &r
)) {
110 php_stream_from_zval(s
, r
);
112 if (SUCCESS
!= php_stream_cast(s
, PHP_STREAM_AS_FD
| PHP_STREAM_CAST_INTERNAL
, (void **)&fd
, 1)) {
116 PSI_ContextDump(&PSI_G(context
), fd
);
119 ZEND_BEGIN_ARG_INFO_EX(ai_psi_validate
, 0, 0, 1)
120 ZEND_ARG_INFO(0, file
)
122 static PHP_FUNCTION(psi_validate
) {
126 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file
)) {
130 if (!PSI_ParserInit(&P
, file
->val
, psi_error_wrapper
, 0)) {
134 while (0 < PSI_ParserScan(&P
)) {
135 PSI_ParserParse(&P
, PSI_TokenAlloc(&P
));
136 if (P
.num
== PSI_T_EOF
) {
140 PSI_ParserParse(&P
, NULL
);
142 if (0 == PSI_ContextValidateData(NULL
, PSI_DATA(&P
)) && !P
.errors
) {
150 static PHP_MINIT_FUNCTION(psi
)
152 PSI_ContextOps
*ops
= NULL
;
153 zend_class_entry ce
= {0};
155 REGISTER_INI_ENTRIES();
157 INIT_NS_CLASS_ENTRY(ce
, "psi", "object", NULL
);
158 psi_class_entry
= zend_register_internal_class_ex(&ce
, NULL
);
159 psi_class_entry
->create_object
= psi_object_init
;
161 memcpy(&psi_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
162 psi_object_handlers
.offset
= XtOffsetOf(psi_object
, std
);
163 psi_object_handlers
.free_obj
= psi_object_free
;
164 psi_object_handlers
.clone_obj
= NULL
;
167 if (!strcasecmp(PSI_G(engine
), "jit")) {
176 php_error(E_WARNING
, "No PSI engine found");
180 PSI_ContextInit(&PSI_G(context
), ops
, psi_error_wrapper
);
181 PSI_ContextBuild(&PSI_G(context
), PSI_G(directory
));
183 if (psi_check_env("PSI_DUMP")) {
184 PSI_ContextDump(&PSI_G(context
), STDOUT_FILENO
);
190 static PHP_MSHUTDOWN_FUNCTION(psi
)
192 PSI_ContextDtor(&PSI_G(context
));
194 UNREGISTER_INI_ENTRIES();
199 #if defined(COMPILE_DL_PSI) && defined(ZTS)
200 static PHP_RINIT_FUNCTION(psi
)
202 ZEND_TSRMLS_CACHE_UPDATE();
207 static PHP_MINFO_FUNCTION(psi
)
209 php_info_print_table_start();
210 php_info_print_table_header(2, "psi support", "enabled");
211 php_info_print_table_end();
213 DISPLAY_INI_ENTRIES();
216 static const zend_function_entry psi_functions
[] = {
217 PHP_FE(psi_dump
, ai_psi_dump
)
218 PHP_FE(psi_validate
, ai_psi_validate
)
222 zend_module_entry psi_module_entry
= {
223 STANDARD_MODULE_HEADER
,
228 #if defined(COMPILE_DL_PSI) && defined(ZTS)
229 PHP_RINIT(psi
), /* Replace with NULL if there's nothing to do at request start */
236 STANDARD_MODULE_PROPERTIES
239 #ifdef COMPILE_DL_PSI
241 ZEND_TSRMLS_CACHE_DEFINE();
251 * vim600: noet sw=4 ts=4 fdm=marker
252 * vim<600: noet sw=4 ts=4