055ba1b125ece773ddb560c53c7c56f79fbd8b76
7 static void psi_jit_handler(jit_type_t _sig
, void *result
, void **_args
, void *_data
);
9 static inline jit_abi_t
psi_jit_abi(const char *convention
) {
12 static inline jit_type_t
psi_jit_type(token_t t
) {
20 return jit_type_sbyte
;
22 return jit_type_ubyte
;
24 return jit_type_short
;
26 return jit_type_ushort
;
34 return jit_type_ulong
;
36 return jit_type_sys_bool
;
38 return jit_type_sys_int
;
40 return jit_type_sys_float
;
42 return jit_type_sys_double
;
45 static inline jit_type_t
psi_jit_decl_type(decl_type
*type
) {
46 return psi_jit_type(real_decl_type(type
)->type
);
48 static inline jit_type_t
psi_jit_decl_arg_type(decl_arg
*darg
) {
49 if (darg
->var
->pointer_level
) {
50 return jit_type_void_ptr
;
52 return psi_jit_decl_type(darg
->type
);
56 typedef struct PSI_LibjitContext
{
60 struct PSI_LibjitData
**list
;
65 typedef struct PSI_LibjitData
{
66 PSI_LibjitContext
*context
;
68 zend_internal_arg_info
*arginfo
;
74 static inline PSI_LibjitData
*PSI_LibjitDataAlloc(PSI_LibjitContext
*context
, impl
*impl
) {
75 size_t i
, c
= impl
->decl
->args
->count
;
76 PSI_LibjitData
*data
= malloc(sizeof(*data
) + (c
? c
-1 : c
) * sizeof(jit_type_t
));
78 data
->context
= context
;
80 data
->arginfo
= psi_internal_arginfo(impl
);
81 for (i
= 0; i
< c
; ++i
) {
82 data
->params
[i
] = psi_jit_decl_arg_type(impl
->decl
->args
->args
[i
]);
85 data
->signature
= jit_type_create_signature(
86 psi_jit_abi(data
->impl
->decl
->abi
->convention
),
87 psi_jit_decl_arg_type(data
->impl
->decl
->func
),
89 data
->impl
->decl
->args
->count
,
91 data
->closure
= jit_closure_create(context
->jit
, context
->signature
, &psi_jit_handler
, data
);
93 context
->data
.list
= realloc(context
->data
.list
, ++context
->data
.count
* sizeof(*context
->data
.list
));
94 context
->data
.list
[context
->data
.count
-1] = data
;
99 static inline void PSI_LibjitDataFree(PSI_LibjitData
*data
) {
101 jit_type_free(data
->signature
);
105 static inline PSI_LibjitContext
*PSI_LibjitContextInit(PSI_LibjitContext
*L
) {
106 jit_type_t params
[] = {
112 L
= malloc(sizeof(*L
));
114 memset(L
, 0, sizeof(*L
));
116 L
->jit
= jit_context_create();
117 L
->signature
= jit_type_create_signature(jit_abi_cdecl
, jit_type_void
, params
, 2, 1);
122 static inline void PSI_LibjitContextDtor(PSI_LibjitContext
*L
) {
125 for (i
= 0; i
< L
->data
.count
; ++i
) {
126 PSI_LibjitDataFree(L
->data
.list
[i
]);
131 jit_type_free(L
->signature
);
132 jit_context_destroy(L
->jit
);
135 static inline void PSI_LibjitContextFree(PSI_LibjitContext
**L
) {
137 PSI_LibjitContextDtor(*L
);
143 static void psi_jit_handler(jit_type_t _sig
, void *result
, void **_args
, void *_data
)
145 PSI_LibjitData
*data
= _data
;
147 void **arg_prm
= NULL
;
150 if (SUCCESS
!= psi_parse_args(*(zend_execute_data
**)_args
[0], data
->impl
)) {
154 if (data
->impl
->decl
->args
->count
) {
155 arg_prm
= malloc(data
->impl
->decl
->args
->count
* sizeof(*arg_prm
));
157 for (i
= 0; i
< data
->impl
->decl
->args
->count
; ++i
) {
158 decl_arg
*darg
= data
->impl
->decl
->args
->args
[i
];
160 arg_prm
[i
] = psi_do_let(darg
);
164 jit_apply(data
->signature
, data
->impl
->decl
->dlptr
, arg_prm
, data
->impl
->decl
->args
->count
, &ret_val
);
166 psi_do_return(data
->impl
, &ret_val
, *(zval
**)_args
[1]);
168 for (i
= 0; i
< data
->impl
->stmts
->set
.count
; ++i
) {
169 set_stmt
*set
= data
->impl
->stmts
->set
.list
[i
];
172 psi_do_set(set
->arg
->_zv
, set
->val
->func
, set
->val
->vars
);
176 for (i
= 0; i
< data
->impl
->stmts
->fre
.count
; ++i
) {
177 free_stmt
*fre
= data
->impl
->stmts
->fre
.list
[i
];
182 psi_do_clean(data
->impl
);
189 static void psi_jit_init(PSI_Context
*C
)
191 C
->context
= PSI_LibjitContextInit(NULL
);
194 static void psi_jit_dtor(PSI_Context
*C
)
196 PSI_LibjitContextFree((void *) &C
->context
);
199 static zend_function_entry
*psi_jit_compile(PSI_Context
*C
, PSI_Data
*D
)
202 zend_function_entry
*zfe
= calloc(D
->impls
->count
+ 1, sizeof(*zfe
));
203 PSI_LibjitContext
*ctx
= C
->context
;
205 jit_context_build_start(ctx
->jit
);
207 for (i
= 0; i
< D
->impls
->count
; ++i
) {
208 zend_function_entry
*zf
= &zfe
[j
];
209 PSI_LibjitData
*data
;
211 if (!D
->impls
->list
[i
]->decl
) {
215 data
= PSI_LibjitDataAlloc(ctx
, D
->impls
->list
[i
]);
216 zf
->fname
= D
->impls
->list
[i
]->func
->name
+ (D
->impls
->list
[i
]->func
->name
[0] == '\\');
217 zf
->num_args
= D
->impls
->list
[i
]->func
->args
->count
;
218 zf
->handler
= data
->closure
;
219 zf
->arg_info
= data
->arginfo
;
223 jit_context_build_end(ctx
->jit
);
228 static PSI_ContextOps ops
= {
234 PSI_ContextOps
*PSI_Libjit(void)