Skip to content

Commit 8d9b682

Browse files
committed
JIT support for FFI calls (incomplete)
1 parent ac60b9d commit 8d9b682

File tree

6 files changed

+590
-35
lines changed

6 files changed

+590
-35
lines changed

ext/opcache/jit/zend_jit.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,36 @@ static bool zend_jit_ffi_supported_type(zend_ffi_type *type)
6767
return true;
6868
}
6969

70+
static bool zend_jit_ffi_supported_func(zend_ffi_type *type)
71+
{
72+
zend_ffi_type *t;
73+
74+
type = ZEND_FFI_TYPE(type);
75+
76+
if (type->func.abi != ZEND_FFI_ABI_CDECL
77+
&& type->func.abi != ZEND_FFI_ABI_FASTCALL) {
78+
return false;
79+
}
80+
81+
t = ZEND_FFI_TYPE(type->func.ret_type);
82+
if (t->kind == ZEND_FFI_TYPE_STRUCT
83+
|| !zend_jit_ffi_supported_type(t)) {
84+
return false;
85+
}
86+
87+
if (type->func.args) {
88+
ZEND_HASH_PACKED_FOREACH_PTR(type->func.args, t) {
89+
t = ZEND_FFI_TYPE(t);
90+
if (t->kind == ZEND_FFI_TYPE_STRUCT
91+
|| !zend_jit_ffi_supported_type(t)) {
92+
return false;
93+
}
94+
} ZEND_HASH_FOREACH_END();
95+
}
96+
97+
return true;
98+
}
99+
70100
static bool zend_jit_ffi_compatible(zend_ffi_type *dst_type, uint32_t src_info, zend_ffi_type *src_type)
71101
{
72102
dst_type = ZEND_FFI_TYPE(dst_type);

ext/opcache/jit/zend_jit_helpers.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3271,3 +3271,37 @@ static zend_string* ZEND_FASTCALL zend_jit_rope_end(zend_string **rope, uint32_t
32713271
*target = '\0';
32723272
return ret;
32733273
}
3274+
3275+
#ifdef HAVE_FFI
3276+
static void ZEND_FASTCALL zend_jit_zval_string(zval *zv, const char *str)
3277+
{
3278+
if (str) {
3279+
ZVAL_STRING(zv, str);
3280+
} else {
3281+
ZVAL_NULL(zv);
3282+
}
3283+
}
3284+
3285+
static void ZEND_FASTCALL zend_jit_zval_ffi_ptr(zval *zv, zend_ffi_type *type, void *ptr)
3286+
{
3287+
ZEND_ASSERT(type->kind == ZEND_FFI_TYPE_POINTER);
3288+
if (ptr) {
3289+
zend_ffi_cdata *cdata = emalloc(sizeof(zend_ffi_cdata));
3290+
3291+
// inlined zend_ffi_object_init()
3292+
GC_SET_REFCOUNT(&cdata->std, 1);
3293+
GC_TYPE_INFO(&cdata->std) = GC_OBJECT | (IS_OBJ_DESTRUCTOR_CALLED << GC_FLAGS_SHIFT);
3294+
cdata->std.ce = zend_ffi_cdata_ce;
3295+
cdata->std.handlers = zend_ffi_cdata_ce->default_object_handlers; /* zend_ffi_cdata_handlers */
3296+
cdata->std.properties = NULL;
3297+
zend_objects_store_put(&cdata->std);
3298+
cdata->type = type;
3299+
cdata->flags = 0;
3300+
cdata->ptr = (void*)&cdata->ptr_holder;
3301+
cdata->ptr_holder = ptr;
3302+
ZVAL_OBJ(zv, &cdata->std);
3303+
} else {
3304+
ZVAL_NULL(zv);
3305+
}
3306+
}
3307+
#endif

ext/opcache/jit/zend_jit_internal.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,12 @@ typedef enum _zend_jit_trace_op {
381381
#define ZEND_JIT_TRACE_FAKE_INFO(level) \
382382
(((level) << ZEND_JIT_TRACE_FAKE_LEVEL_SHIFT) | ZEND_JIT_TRACE_FAKE_INIT_CALL)
383383

384+
#define ZEND_JIT_TRACE_NUM_ARGS_INFO(count) \
385+
((count) << ZEND_JIT_TRACE_FAKE_LEVEL_SHIFT)
386+
387+
#define ZEND_JIT_TRACE_NUM_ARGS(info) \
388+
(((info) & ZEND_JIT_TRACE_FAKE_LEVEL_MASK) >> ZEND_JIT_TRACE_FAKE_LEVEL_SHIFT)
389+
384390
#define ZEND_JIT_TRACE_SET_FIRST_SSA_VAR(_info, var) do { \
385391
_info |= (var << ZEND_JIT_TRACE_SSA_VAR_SHIFT); \
386392
} while (0)
@@ -564,6 +570,8 @@ struct _zend_jit_trace_stack_frame {
564570
#define TRACE_FRAME_MASK_CLOSURE_CALL 0x00000200
565571
#define TRACE_FRAME_MASK_ALWAYS_RELEASE_THIS 0x00000400
566572

573+
#define TRACE_FRAME_MASK_FFI 0x00000800
574+
567575

568576
#define TRACE_FRAME_INIT(frame, _func, _flags, num_args) do { \
569577
zend_jit_trace_stack_frame *_frame = (frame); \
@@ -602,6 +610,8 @@ struct _zend_jit_trace_stack_frame {
602610
((frame)->_info & TRACE_FRAME_MASK_CLOSURE_CALL)
603611
#define TRACE_FRAME_ALWAYS_RELEASE_THIS(frame) \
604612
((frame)->_info & TRACE_FRAME_MASK_ALWAYS_RELEASE_THIS)
613+
#define TRACE_FRAME_FFI(frame) \
614+
((frame)->_info & TRACE_FRAME_MASK_FFI)
605615

606616
#define TRACE_FRAME_SET_UNKNOWN_NUM_ARGS(frame) do { \
607617
(frame)->_info |= (0xffffu << TRACE_FRAME_SHIFT_NUM_ARGS); \

0 commit comments

Comments
 (0)