4 # include "php_config.h"
9 #include "ext/standard/info.h"
10 #include "zend_constants.h"
11 #include "zend_operators.h"
20 # define PSI_ENGINE "jit"
25 # define PSI_ENGINE "ffi"
28 ZEND_DECLARE_MODULE_GLOBALS(psi
);
31 STD_PHP_INI_ENTRY("psi.engine", PSI_ENGINE
, PHP_INI_SYSTEM
, OnUpdateString
, engine
, zend_psi_globals
, psi_globals
)
32 STD_PHP_INI_ENTRY("psi.directory", "psi.d", PHP_INI_SYSTEM
, OnUpdateString
, directory
, zend_psi_globals
, psi_globals
)
35 static zend_object_handlers psi_object_handlers
;
36 static zend_class_entry
*psi_class_entry
;
38 zend_class_entry
*psi_object_get_class_entry()
40 return psi_class_entry
;
43 void psi_error_wrapper(void *context
, struct psi_token
*t
, int type
, const char *msg
, ...)
46 const char *fn
= NULL
;
50 if (PSI_DATA(context
)->flags
& PSI_PARSER_SILENT
) {
58 } else if (zend_is_executing()) {
59 fn
= zend_get_executed_filename();
60 ln
= zend_get_executed_lineno();
61 } else if (zend_is_compiling()) {
62 fn
= zend_get_compiled_filename()->val
;
63 ln
= zend_get_compiled_lineno();
67 psi_verror(type
, fn
, ln
, msg
, argv
);
71 void psi_error(int type
, const char *fn
, unsigned ln
, const char *msg
, ...)
76 psi_verror(type
, fn
, ln
, msg
, argv
);
80 void psi_verror(int type
, const char *fn
, unsigned ln
, const char *msg
, va_list argv
)
82 zend_error_cb(type
, fn
, ln
, msg
, argv
);
85 static void psi_object_free(zend_object
*o
)
87 psi_object
*obj
= PSI_OBJ(NULL
, o
);
90 /* FIXME: how about registering a destructor?
91 // free(obj->data); */
94 zend_object_std_dtor(o
);
97 static zend_object
*psi_object_init(zend_class_entry
*ce
)
99 psi_object
*o
= ecalloc(1, sizeof(*o
) + zend_object_properties_size(ce
));
101 zend_object_std_init(&o
->std
, ce
);
102 object_properties_init(&o
->std
, ce
);
103 o
->std
.handlers
= &psi_object_handlers
;
107 ZEND_BEGIN_ARG_INFO_EX(ai_psi_dump
, 0, 0, 0)
108 ZEND_ARG_INFO(0, stream
)
110 static PHP_FUNCTION(psi_dump
) {
113 int fd
= STDOUT_FILENO
;
115 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS(), "|r!", &r
)) {
119 php_stream_from_zval(s
, r
);
121 if (SUCCESS
!= php_stream_cast(s
, PHP_STREAM_AS_FD
| PHP_STREAM_CAST_INTERNAL
, (void **)&fd
, 1)) {
125 psi_context_dump(&PSI_G(context
), fd
);
128 ZEND_BEGIN_ARG_INFO_EX(ai_psi_validate
, 0, 0, 1)
129 ZEND_ARG_INFO(0, file
)
131 static PHP_FUNCTION(psi_validate
) {
135 if (SUCCESS
!= zend_parse_parameters(ZEND_NUM_ARGS(), "P", &file
)) {
139 if (!psi_parser_init(&P
, file
->val
, psi_error_wrapper
, 0)) {
143 while (0 < psi_parser_scan(&P
)) {
144 psi_parser_parse(&P
, psi_token_alloc(&P
));
145 if (P
.num
== PSI_T_EOF
) {
149 psi_parser_parse(&P
, NULL
);
151 if (0 == psi_context_validate_data(NULL
, PSI_DATA(&P
)) && !P
.errors
) {
159 static PHP_MINIT_FUNCTION(psi
)
161 struct psi_context_ops
*ops
= NULL
;
162 zend_class_entry ce
= {0};
163 unsigned flags
= psi_check_env("PSI_DEBUG") ? PSI_PARSER_DEBUG
: (
164 psi_check_env("PSI_SILENT") ? PSI_PARSER_SILENT
: 0);
166 REGISTER_INI_ENTRIES();
168 INIT_NS_CLASS_ENTRY(ce
, "psi", "object", NULL
);
169 psi_class_entry
= zend_register_internal_class_ex(&ce
, NULL
);
170 psi_class_entry
->create_object
= psi_object_init
;
172 memcpy(&psi_object_handlers
, zend_get_std_object_handlers(), sizeof(zend_object_handlers
));
173 psi_object_handlers
.offset
= XtOffsetOf(psi_object
, std
);
174 psi_object_handlers
.free_obj
= psi_object_free
;
175 psi_object_handlers
.clone_obj
= NULL
;
178 if (!strcasecmp(PSI_G(engine
), "jit")) {
179 ops
= psi_libjit_ops();
183 ops
= psi_libffi_ops();
187 php_error(E_WARNING
, "No PSI engine found");
191 psi_context_init(&PSI_G(context
), ops
, psi_error_wrapper
, flags
);
192 psi_context_build(&PSI_G(context
), PSI_G(directory
));
194 if (psi_check_env("PSI_DUMP")) {
195 psi_context_dump(&PSI_G(context
), STDOUT_FILENO
);
201 static PHP_MSHUTDOWN_FUNCTION(psi
)
203 psi_context_dtor(&PSI_G(context
));
205 UNREGISTER_INI_ENTRIES();
210 #if defined(COMPILE_DL_PSI) && defined(ZTS)
211 static PHP_RINIT_FUNCTION(psi
)
213 ZEND_TSRMLS_CACHE_UPDATE();
218 static PHP_MINFO_FUNCTION(psi
)
220 php_info_print_table_start();
221 php_info_print_table_header(2, "psi support", "enabled");
222 php_info_print_table_end();
224 DISPLAY_INI_ENTRIES();
227 static const zend_function_entry psi_functions
[] = {
228 PHP_FE(psi_dump
, ai_psi_dump
)
229 PHP_FE(psi_validate
, ai_psi_validate
)
233 zend_module_entry psi_module_entry
= {
234 STANDARD_MODULE_HEADER
,
239 #if defined(COMPILE_DL_PSI) && defined(ZTS)
240 PHP_RINIT(psi
), /* Replace with NULL if there's nothing to do at request start */
247 STANDARD_MODULE_PROPERTIES
250 #ifdef COMPILE_DL_PSI
252 ZEND_TSRMLS_CACHE_DEFINE();
262 * vim600: noet sw=4 ts=4 fdm=marker
263 * vim<600: noet sw=4 ts=4