e1d6cf866252f9bd8ae07d2685bc73e0a786fc61
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(*(zval
**)_args
[1], data
->impl
->stmts
->ret
.list
[0], &ret_val
);
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
);
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
)
202 zend_function_entry
*zfe
;
203 PSI_LibjitContext
*ctx
= C
->context
;
209 zfe
= calloc(C
->impls
->count
+ 1, sizeof(*zfe
));
210 jit_context_build_start(ctx
->jit
);
212 for (i
= 0; i
< C
->impls
->count
; ++i
) {
213 zend_function_entry
*zf
= &zfe
[j
];
214 PSI_LibjitData
*data
;
216 if (!C
->impls
->list
[i
]->decl
) {
220 data
= PSI_LibjitDataAlloc(ctx
, C
->impls
->list
[i
]);
221 zf
->fname
= C
->impls
->list
[i
]->func
->name
+ (C
->impls
->list
[i
]->func
->name
[0] == '\\');
222 zf
->num_args
= C
->impls
->list
[i
]->func
->args
->count
;
223 zf
->handler
= data
->closure
;
224 zf
->arg_info
= data
->arginfo
;
228 jit_context_build_end(ctx
->jit
);
233 static void psi_jit_call(PSI_Context
*C
, impl_val
*ret_val
, decl
*decl
, impl_val
**args
) {
234 jit_type_t signature
, *types
;
238 /* FIXME: cache in decl */
240 types
= calloc(decl
->args
->count
+ 1, sizeof(*types
));
241 argps
= calloc(decl
->args
->count
+ 1, sizeof(*argps
));
242 for (i
= 0; i
< decl
->args
->count
; ++i
) {
243 decl_arg
*darg
= decl
->args
->args
[i
];
245 types
[i
] = psi_jit_decl_arg_type(darg
);
249 signature
= jit_type_create_signature(
250 psi_jit_abi(decl
->abi
->convention
),
251 psi_jit_decl_arg_type(decl
->func
),
252 types
, decl
->args
->count
, 1);
253 jit_apply(signature
, decl
->dlptr
, argps
, decl
->args
->count
, ret_val
);
255 jit_type_free(signature
);
261 static PSI_ContextOps ops
= {
268 PSI_ContextOps
*PSI_Libjit(void)