6 #include <Zend/Zend_API.h>
10 PSI_Compiler
*PSI_CompilerInit(PSI_Compiler
*C
, PSI_Validator
*V
, void *context
)
13 C
= malloc(sizeof(*C
));
15 memset(C
, 0, sizeof(*C
));
17 PSI_DataExchange((PSI_Data
*) C
, (PSI_Data
*) V
);
24 void PSI_CompilerDtor(PSI_Compiler
*C
)
26 PSI_DataDtor((PSI_Data
*) C
);
29 void PSI_Compiler_Free(PSI_Compiler
**C
)
38 typedef struct PSI_ClosureData
{
43 static inline PSI_ClosureData
*PSI_ClosureDataAlloc(void *context
, impl
*impl
) {
44 PSI_ClosureData
*data
= malloc(sizeof(*data
));
46 data
->context
= context
;
52 static inline size_t impl_num_min_args(impl
*impl
) {
53 size_t i
, n
= impl
->func
->args
->count
;
55 for (i
= 0; i
< impl
->func
->args
->count
; ++i
) {
56 if (impl
->func
->args
->args
[i
]->def
) {
63 void jit_closure_handler(jit_type_t signature
, void *result
, void **args
, void *user_data
)
65 zend_execute_data
*execute_data
= args
[0];
66 zval
*return_value
= args
[1];
67 PSI_ClosureData
*data
= user_data
;
70 if (!data
->impl
->func
->args
->count
) {
71 if (SUCCESS
!= zend_parse_parameters_none()) {
75 ZEND_PARSE_PARAMETERS_START(impl_num_min_args(data
->impl
), data
->impl
->func
->args
->count
)
77 iarg
= data
->impl
->func
->args
->args
[_i
];
81 if (PSI_T_BOOL
== iarg
->type
->type
) {
83 iarg
->val
.bval
= iarg
->def
->type
== PSI_T_TRUE
? 1 : 0;
85 Z_PARAM_BOOL(iarg
->val
.bval
);
86 } else if (PSI_T_INT
== iarg
->type
->type
) {
88 iarg
->val
.lval
= atol(iarg
->def
->text
);
90 Z_PARAM_LONG(iarg
->val
.lval
);
91 } else if (PSI_T_FLOAT
== iarg
->type
->type
) {
93 iarg
->val
.dval
= strtod(iarg
->def
->text
, NULL
);
95 Z_PARAM_DOUBLE(iarg
->val
.dval
);
96 } else if (PSI_T_STRING
== iarg
->type
->type
) {
99 iarg
->val
.str
.len
= strlen(iarg
->def
->text
) - 2;
100 iarg
->val
.str
.val
= &iarg
->def
->text
[1];
102 Z_PARAM_STRING(iarg
->val
.str
.val
, iarg
->val
.str
.len
);
104 error_code
= ZPP_ERROR_FAILURE
;
108 ZEND_PARSE_PARAMETERS_END();
111 zend_function_entry
*PSI_CompilerCompile(PSI_Compiler
*C
)
114 jit_type_t signature
, params
[] = {
118 zend_function_entry
*zfe
= calloc(C
->impls
->count
+ 1, sizeof(*zfe
));
120 for (i
= 0; i
< C
->impls
->count
; ++i
) {
121 zend_function_entry
*zf
;
122 PSI_ClosureData
*data
;
124 if (!C
->impls
->list
[i
]->decl
) {
127 signature
= jit_type_create_signature(jit_abi_cdecl
, jit_type_void
, params
, 2, 1);
130 data
= PSI_ClosureDataAlloc(C
->context
, C
->impls
->list
[i
]);
131 zf
->fname
= C
->impls
->list
[i
]->func
->name
;
132 zf
->handler
= jit_closure_create(C
->context
, signature
, jit_closure_handler
, data
);