Skip to content

Commit 1e067d5

Browse files
committed
JIT for FFI::typeof() and FFI:isNull()
1 parent 523f745 commit 1e067d5

File tree

5 files changed

+118
-7
lines changed

5 files changed

+118
-7
lines changed

ext/ffi/ffi.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,16 @@ static zend_ffi_cdata* zend_ffi_cdata_create(void *ptr, zend_ffi_type *type) /*
372372
}
373373
/* }}} */
374374

375+
static zend_ffi_ctype* zend_ffi_ctype_create(zend_ffi_type *type) /* {{{ */
376+
{
377+
zend_ffi_ctype *ctype = emalloc(sizeof(zend_ffi_ctype));
378+
379+
zend_ffi_object_init(&ctype->std, zend_ffi_ctype_ce);
380+
ctype->type = type;
381+
return ctype;
382+
}
383+
/* }}} */
384+
375385
static zend_never_inline zend_ffi_cdata *zend_ffi_cdata_to_zval_slow(void *ptr, zend_ffi_type *type, zend_ffi_flags flags) /* {{{ */
376386
{
377387
zend_ffi_cdata *cdata = emalloc(sizeof(zend_ffi_cdata));
@@ -5611,8 +5621,10 @@ ZEND_MINIT_FUNCTION(ffi)
56115621

56125622
ffi_api.scope_ce = zend_ffi_ce;
56135623
ffi_api.cdata_ce = zend_ffi_cdata_ce;
5624+
ffi_api.ctype_ce = zend_ffi_ctype_ce;
56145625

56155626
ffi_api.cdata_create = zend_ffi_cdata_create;
5627+
ffi_api.ctype_create = zend_ffi_ctype_create;
56165628
ffi_api.type_print = zend_ffi_type_print;
56175629
ffi_api.is_compatible_type = zend_ffi_is_compatible_type;
56185630

ext/ffi/php_ffi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,8 +416,10 @@ typedef struct _zend_ffi {
416416
struct _zend_ffi_api {
417417
zend_class_entry *scope_ce;
418418
zend_class_entry *cdata_ce;
419+
zend_class_entry *ctype_ce;
419420

420421
zend_ffi_cdata* (*cdata_create)(void *ptr, zend_ffi_type *type);
422+
zend_ffi_ctype* (*ctype_create)(zend_ffi_type *type);
421423
void (*type_print)(FILE *f, const zend_ffi_type *type);
422424
bool (*is_compatible_type)(zend_ffi_type *dst_type, zend_ffi_type *src_type);
423425

ext/opcache/jit/zend_jit_internal.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -583,12 +583,13 @@ struct _zend_jit_trace_stack_frame {
583583
#define TRACE_FRAME_FFI_FUNC_TYPEOF 0x00004000
584584
#define TRACE_FRAME_FFI_FUNC_ARRAY_TYPE 0x00005000
585585
#define TRACE_FRAME_FFI_FUNC_ADDR 0x00006000
586-
#define TRACE_FRAME_FFI_FUNC_SIZEOF 0x00007000
587-
#define TRACE_FRAME_FFI_FUNC_MEMCPY 0x00008000
588-
#define TRACE_FRAME_FFI_FUNC_MEMCMP 0x00009000
589-
#define TRACE_FRAME_FFI_FUNC_MEMSET 0x0000a000
590-
#define TRACE_FRAME_FFI_FUNC_STRING 0x0000b000
591-
#define TRACE_FRAME_FFI_FUNC_IS_NULL 0x0000c000
586+
#define TRACE_FRAME_FFI_FUNC_ALIGNOF 0x00007000
587+
#define TRACE_FRAME_FFI_FUNC_SIZEOF 0x00008000
588+
#define TRACE_FRAME_FFI_FUNC_MEMCPY 0x00009000
589+
#define TRACE_FRAME_FFI_FUNC_MEMCMP 0x0000a000
590+
#define TRACE_FRAME_FFI_FUNC_MEMSET 0x0000b000
591+
#define TRACE_FRAME_FFI_FUNC_STRING 0x0000c000
592+
#define TRACE_FRAME_FFI_FUNC_IS_NULL 0x0000d000
592593

593594

594595
#define TRACE_FRAME_INIT(frame, _func, _flags, num_args) do { \

ext/opcache/jit/zend_jit_ir_ffi.c

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ static ir_ref jit_FFI_CDATA_PTR(zend_jit_ctx *jit, ir_ref obj_ref)
2121
return ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
2222
}
2323

24+
static ir_ref jit_FFI_CDATA_TYPE(zend_jit_ctx *jit, ir_ref obj_ref)
25+
{
26+
return ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, type)));
27+
}
28+
2429
static int zend_jit_ffi_symbols_guard(zend_jit_ctx *jit,
2530
const zend_op *opline,
2631
zend_ssa *ssa,
@@ -116,10 +121,19 @@ static int zend_jit_ffi_send_val(zend_jit_ctx *jit,
116121
uint8_t arg_flags = 0;
117122

118123
if (TRACE_FRAME_FFI_FUNC(call)) {
119-
if (TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_ADDR) {
124+
if (TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_ADDR
125+
|| TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_ALIGNOF
126+
|| TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_SIZEOF
127+
|| TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_TYPEOF
128+
|| TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_IS_NULL) {
120129
ZEND_ASSERT(opline->op2.num == 1);
121130
ZEND_ASSERT(op1_ffi_type);
122131

132+
if (TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_IS_NULL) {
133+
ZEND_ASSERT(op1_ffi_type->kind == ZEND_FFI_TYPE_POINTER);
134+
arg_flags |= ZREG_FFI_PTR_LOAD;
135+
}
136+
123137
if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
124138
arg_flags |= ZREG_FFI_ZVAL_DTOR;
125139
}
@@ -401,6 +415,57 @@ static int zend_jit_ffi_do_call(zend_jit_ctx *jit,
401415
}
402416
jit_set_Z_PTR(jit, res_addr, ref);
403417
jit_set_Z_TYPE_INFO(jit, res_addr, IS_OBJECT_EX);
418+
} else if (TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_ALIGNOF) {
419+
ref = STACK_REF(stack, 0);
420+
if (STACK_FLAGS(stack, 0) & ZREG_FFI_ZVAL_DEREF) {
421+
// TODO: try to remove this dereference ???
422+
ref = zend_jit_gc_deref(jit, ref);
423+
}
424+
ref = jit_FFI_CDATA_TYPE(jit, ref);
425+
// TODO: type flags ???
426+
ref = ir_LOAD_U32(ir_ADD_OFFSET(ref, offsetof(zend_ffi_type, align)));
427+
if (sizeof(void*) == 8) {
428+
ref = ir_ZEXT_L(ref);
429+
}
430+
jit_set_Z_LVAL(jit, res_addr, ref);
431+
jit_set_Z_TYPE_INFO(jit, res_addr, IS_LONG);
432+
} else if (TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_SIZEOF) {
433+
ref = STACK_REF(stack, 0);
434+
if (STACK_FLAGS(stack, 0) & ZREG_FFI_ZVAL_DEREF) {
435+
// TODO: try to remove this dereference ???
436+
ref = zend_jit_gc_deref(jit, ref);
437+
}
438+
ref = jit_FFI_CDATA_TYPE(jit, ref);
439+
// TODO: type flags ???
440+
ref = ir_LOAD_U32(ir_ADD_OFFSET(ref, offsetof(zend_ffi_type, size)));
441+
if (sizeof(void*) == 8) {
442+
ref = ir_ZEXT_L(ref);
443+
}
444+
jit_set_Z_LVAL(jit, res_addr, ref);
445+
jit_set_Z_TYPE_INFO(jit, res_addr, IS_LONG);
446+
} else if (TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_TYPEOF) {
447+
ref = STACK_REF(stack, 0);
448+
if (STACK_FLAGS(stack, 0) & ZREG_FFI_ZVAL_DEREF) {
449+
// TODO: try to remove this dereference ???
450+
ref = zend_jit_gc_deref(jit, ref);
451+
}
452+
ref = jit_FFI_CDATA_TYPE(jit, ref);
453+
// TODO: type flags ???
454+
ref = ir_CALL_1(IR_ADDR, ir_CONST_FUNC(zend_ffi_api->ctype_create), ref);
455+
jit_set_Z_PTR(jit, res_addr, ref);
456+
jit_set_Z_TYPE_INFO(jit, res_addr, IS_OBJECT_EX);
457+
} else if (TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_IS_NULL) {
458+
ref = STACK_REF(stack, 0);
459+
if (STACK_FLAGS(stack, 0) & ZREG_FFI_ZVAL_DEREF) {
460+
// TODO: try to remove this dereference ???
461+
ref = zend_jit_gc_deref(jit, ref);
462+
}
463+
ref = jit_FFI_CDATA_TYPE(jit, ref);
464+
if (STACK_FLAGS(stack, 0) & ZREG_FFI_PTR_LOAD) {
465+
ref = ir_LOAD_A(ref);
466+
}
467+
ref = ir_ADD_U32(ir_ZEXT_U32(ir_EQ(ref, IR_NULL)), ir_CONST_U32(IS_FALSE));
468+
jit_set_Z_TYPE_INFO_ex(jit, res_addr, ref);
404469
} else if (TRACE_FRAME_FFI_FUNC(call) == TRACE_FRAME_FFI_FUNC_STRING) {
405470
ZEND_ASSERT(num_args > 0 && STACK_TYPE(stack, 0) == IS_OBJECT);
406471
ref = STACK_REF(stack, 0);

ext/opcache/jit/zend_jit_trace.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6996,6 +6996,37 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
69966996
frame_ffi_func_type = NULL;
69976997
frame_ffi_func_ref = IR_UNUSED;
69986998
goto done;
6999+
#if 0
7000+
// TODO: add support for FFI::CType argument ???
7001+
} else if (Z_TYPE_P(zv) == IS_STRING
7002+
&& zend_string_equals_literal_ci(Z_STR_P(zv), "alignof")
7003+
&& opline->extended_value == 1) {
7004+
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_ALIGNOF;
7005+
frame_ffi_func_type = NULL;
7006+
frame_ffi_func_ref = IR_UNUSED;
7007+
goto done;
7008+
} else if (Z_TYPE_P(zv) == IS_STRING
7009+
&& zend_string_equals_literal_ci(Z_STR_P(zv), "sizeof")
7010+
&& opline->extended_value == 1) {
7011+
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_SIZEOF;
7012+
frame_ffi_func_type = NULL;
7013+
frame_ffi_func_ref = IR_UNUSED;
7014+
goto done;
7015+
#endif
7016+
} else if (Z_TYPE_P(zv) == IS_STRING
7017+
&& zend_string_equals_literal_ci(Z_STR_P(zv), "typeof")
7018+
&& opline->extended_value == 1) {
7019+
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_TYPEOF;
7020+
frame_ffi_func_type = NULL;
7021+
frame_ffi_func_ref = IR_UNUSED;
7022+
goto done;
7023+
} else if (Z_TYPE_P(zv) == IS_STRING
7024+
&& zend_string_equals_literal_ci(Z_STR_P(zv), "isnull")
7025+
&& opline->extended_value == 1) {
7026+
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_IS_NULL;
7027+
frame_ffi_func_type = NULL;
7028+
frame_ffi_func_ref = IR_UNUSED;
7029+
goto done;
69997030
}
70007031
}
70017032
}

0 commit comments

Comments
 (0)