Skip to content

Commit a75bec6

Browse files
committed
Allow JIT for reading FFI arrays/structs/pointers
1 parent 0ccf4b9 commit a75bec6

File tree

3 files changed

+41
-3
lines changed

3 files changed

+41
-3
lines changed

ext/opcache/jit/zend_jit_helpers.c

+23
Original file line numberDiff line numberDiff line change
@@ -3304,4 +3304,27 @@ static void ZEND_FASTCALL zend_jit_zval_ffi_ptr(zval *zv, zend_ffi_type *type, v
33043304
ZVAL_NULL(zv);
33053305
}
33063306
}
3307+
3308+
static void ZEND_FASTCALL zend_jit_zval_ffi_obj(zval *zv, zend_ffi_type *type, void *ptr)
3309+
{
3310+
if (!ptr) {
3311+
ZEND_ASSERT(type->kind == ZEND_FFI_TYPE_POINTER);
3312+
ZVAL_NULL(zv);
3313+
} else {
3314+
zend_ffi_cdata *cdata = emalloc(sizeof(zend_ffi_cdata));
3315+
3316+
// inlined zend_ffi_object_init()
3317+
GC_SET_REFCOUNT(&cdata->std, 1);
3318+
GC_TYPE_INFO(&cdata->std) = GC_OBJECT | (IS_OBJ_DESTRUCTOR_CALLED << GC_FLAGS_SHIFT);
3319+
cdata->std.ce = zend_ffi_cdata_ce;
3320+
cdata->std.handlers = zend_ffi_cdata_ce->default_object_handlers; /* zend_ffi_cdata_handlers */
3321+
cdata->std.properties = NULL;
3322+
zend_objects_store_put(&cdata->std);
3323+
cdata->type = type;
3324+
cdata->flags = 0;
3325+
cdata->ptr = ptr;
3326+
cdata->ptr_holder = NULL;
3327+
ZVAL_OBJ(zv, &cdata->std);
3328+
}
3329+
}
33073330
#endif

ext/opcache/jit/zend_jit_ir.c

+18
Original file line numberDiff line numberDiff line change
@@ -3082,6 +3082,7 @@ static void zend_jit_setup_disasm(void)
30823082
#ifdef HAVE_FFI
30833083
REGISTER_HELPER(zend_jit_zval_string);
30843084
REGISTER_HELPER(zend_jit_zval_ffi_ptr);
3085+
REGISTER_HELPER(zend_jit_zval_ffi_obj);
30853086
#endif
30863087

30873088
#ifndef ZTS
@@ -12960,6 +12961,23 @@ static int zend_jit_ffi_read(zend_jit_ctx *jit,
1296012961
ir_MUL_L(ir_ZEXT_L(ir_LOAD_U8(ptr)), ir_CONST_LONG(sizeof(void*))))));
1296112962
res_type = IS_STRING;
1296212963
break;
12964+
case ZEND_FFI_TYPE_ARRAY:
12965+
case ZEND_FFI_TYPE_STRUCT:
12966+
ir_CALL_3(IR_VOID, ir_CONST_FC_FUNC(zend_jit_zval_ffi_obj),
12967+
jit_ZVAL_ADDR(jit, res_addr), ir_CONST_ADDR(ffi_type), ptr);
12968+
return 1;
12969+
case ZEND_FFI_TYPE_POINTER:
12970+
if ((ffi_type->attr & ZEND_FFI_ATTR_CONST)
12971+
&& ZEND_FFI_TYPE(ffi_type->pointer.type)->kind == ZEND_FFI_TYPE_CHAR) {
12972+
ir_CALL_2(IR_VOID, ir_CONST_FC_FUNC(zend_jit_zval_string), jit_ZVAL_ADDR(jit, res_addr), ptr);
12973+
return 1;
12974+
} else {
12975+
ir_CALL_3(IR_VOID, ir_CONST_FC_FUNC(zend_jit_zval_ffi_ptr),
12976+
jit_ZVAL_ADDR(jit, res_addr), ir_CONST_ADDR(ffi_type), ir_LOAD_A(ptr));
12977+
return 1;
12978+
}
12979+
break;
12980+
break;
1296312981
default:
1296412982
ZEND_UNREACHABLE();
1296512983
}

ext/opcache/jit/zend_jit_trace.c

-3
Original file line numberDiff line numberDiff line change
@@ -5986,7 +5986,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
59865986
if (op1_ffi_type
59875987
&& (op1_ffi_type->kind == ZEND_FFI_TYPE_ARRAY || op1_ffi_type->kind == ZEND_FFI_TYPE_POINTER)
59885988
&& op2_info == MAY_BE_LONG
5989-
&& ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind < ZEND_FFI_TYPE_POINTER
59905989
&& ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind != ZEND_FFI_TYPE_VOID
59915990
&& zend_jit_ffi_supported_type(ZEND_FFI_TYPE(op1_ffi_type->array.type))) {
59925991
if (!ffi_info) {
@@ -6244,7 +6243,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
62446243

62456244
if (field
62466245
&& !field->bits
6247-
&& ZEND_FFI_TYPE(field->type)->kind < ZEND_FFI_TYPE_POINTER
62486246
&& ZEND_FFI_TYPE(field->type)->kind != ZEND_FFI_TYPE_VOID
62496247
&& zend_jit_ffi_supported_type(ZEND_FFI_TYPE(field->type))) {
62506248
if (!ffi_info) {
@@ -6266,7 +6264,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
62666264
Z_STR_P(RT_CONSTANT(opline, opline->op2)));
62676265
if (sym
62686266
&& sym->kind == ZEND_FFI_SYM_VAR
6269-
&& ZEND_FFI_TYPE(sym->type)->kind < ZEND_FFI_TYPE_POINTER
62706267
&& ZEND_FFI_TYPE(sym->type)->kind != ZEND_FFI_TYPE_VOID
62716268
&& zend_jit_ffi_supported_type(ZEND_FFI_TYPE(sym->type))) {
62726269
if (!ffi_info) {

0 commit comments

Comments
 (0)