Skip to content

Commit b43811f

Browse files
committed
JIT/FFI support for temporary POINTER types (e.g. created by FFI::addr)
1 parent 99c4d8e commit b43811f

File tree

5 files changed

+77
-12
lines changed

5 files changed

+77
-12
lines changed

ext/ffi/ffi.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,6 @@ static const char *zend_ffi_tag_kind_name[3] = {"enum", "struct", "union"};
6464

6565
#include "ffi_arginfo.h"
6666

67-
#define ZEND_FFI_TYPE_MAKE_OWNED(t) \
68-
((zend_ffi_type*)(((uintptr_t)(t)) | ZEND_FFI_TYPE_OWNED))
69-
7067
#define ZEND_FFI_SIZEOF_ARG \
7168
MAX(FFI_SIZEOF_ARG, sizeof(double))
7269

ext/ffi/php_ffi.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -410,6 +410,9 @@ typedef struct _zend_ffi {
410410
#define ZEND_FFI_TYPE_IS_OWNED(t) \
411411
(((uintptr_t)(t)) & ZEND_FFI_TYPE_OWNED)
412412

413+
#define ZEND_FFI_TYPE_MAKE_OWNED(t) \
414+
((zend_ffi_type*)(((uintptr_t)(t)) | ZEND_FFI_TYPE_OWNED))
415+
413416
PHP_FFI_API bool zend_ffi_is_compatible_type(zend_ffi_type *dst_type, zend_ffi_type *src_type);
414417

415418
#endif /* PHP_FFI_H */

ext/opcache/jit/zend_jit_ir_ffi.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,17 @@
1616
* +----------------------------------------------------------------------+
1717
*/
1818

19+
20+
static zend_ffi_type *zend_jit_ffi_type_pointer_to(const zend_ffi_type *type, zend_ffi_type *holder)
21+
{
22+
holder->kind = ZEND_FFI_TYPE_POINTER;
23+
holder->attr = 0;
24+
holder->size = sizeof(void*);
25+
holder->align = _Alignof(void*);
26+
holder->pointer.type = ZEND_FFI_TYPE(type);
27+
return holder;
28+
}
29+
1930
static ir_ref jit_FFI_CDATA_PTR(zend_jit_ctx *jit, ir_ref obj_ref)
2031
{
2132
return ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
@@ -114,6 +125,12 @@ static int zend_jit_ffi_send_val(zend_jit_ctx *jit,
114125
ir_ref ref = IR_UNUSED;
115126
uint8_t arg_type = IS_UNDEF;
116127
uint8_t arg_flags = 0;
128+
zend_ffi_type type_holder;
129+
130+
if (ZEND_FFI_TYPE_IS_OWNED(op1_ffi_type)) {
131+
/* OWNED flag means POINTER TO */
132+
op1_ffi_type = zend_jit_ffi_type_pointer_to(op1_ffi_type, &type_holder);
133+
}
117134

118135
ZEND_ASSERT(type->kind == ZEND_FFI_TYPE_FUNC);
119136
if (type->attr & ZEND_FFI_ATTR_VARIADIC) {

ext/opcache/jit/zend_jit_trace.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8338,7 +8338,12 @@ static void zend_jit_dump_trace(zend_jit_trace_rec *trace_buffer, zend_ssa *tssa
83388338
fprintf(stderr, " op1(%sobject of class %s: ", ref,
83398339
ZSTR_VAL(p->ce->name));
83408340
p++;
8341-
zend_ffi_type_print(stderr, p->ptr);
8341+
if (ZEND_FFI_TYPE_IS_OWNED(p->ptr)) {
8342+
zend_ffi_type holder;
8343+
zend_ffi_type_print(stderr, zend_jit_ffi_type_pointer_to(p->ptr, &holder));
8344+
} else {
8345+
zend_ffi_type_print(stderr, p->ptr);
8346+
}
83428347
fprintf(stderr, ")");
83438348
} else if ((p+1)->op == ZEND_JIT_TRACE_OP1_FFI_SYMBOLS) {
83448349
fprintf(stderr, " op1(%sobject of class %s: ffi_symbols)", ref,
@@ -8364,7 +8369,12 @@ static void zend_jit_dump_trace(zend_jit_trace_rec *trace_buffer, zend_ssa *tssa
83648369
fprintf(stderr, " op2(%sobject of class %s: ", ref,
83658370
ZSTR_VAL(p->ce->name));
83668371
p++;
8367-
zend_ffi_type_print(stderr, p->ptr);
8372+
if (ZEND_FFI_TYPE_IS_OWNED(p->ptr)) {
8373+
zend_ffi_type holder;
8374+
zend_ffi_type_print(stderr, zend_jit_ffi_type_pointer_to(p->ptr, &holder));
8375+
} else {
8376+
zend_ffi_type_print(stderr, p->ptr);
8377+
}
83688378
fprintf(stderr, ")");
83698379
} else
83708380
#endif
@@ -8386,7 +8396,12 @@ static void zend_jit_dump_trace(zend_jit_trace_rec *trace_buffer, zend_ssa *tssa
83868396
fprintf(stderr, " op3(%sobject of class %s: ", ref,
83878397
ZSTR_VAL(p->ce->name));
83888398
p++;
8389-
zend_ffi_type_print(stderr, p->ptr);
8399+
if (ZEND_FFI_TYPE_IS_OWNED(p->ptr)) {
8400+
zend_ffi_type holder;
8401+
zend_ffi_type_print(stderr, zend_jit_ffi_type_pointer_to(p->ptr, &holder));
8402+
} else {
8403+
zend_ffi_type_print(stderr, p->ptr);
8404+
}
83908405
fprintf(stderr, ")");
83918406
} else
83928407
#endif

ext/opcache/jit/zend_jit_vm_helpers.c

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -718,11 +718,22 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
718718
#ifdef HAVE_FFI
719719
if (ce1 == zend_ffi_cdata_ce) {
720720
zend_ffi_cdata *cdata = (zend_ffi_cdata*)Z_OBJ_P(zv);
721-
if (!ZEND_FFI_TYPE_IS_OWNED(cdata->type)) {
722-
zend_ffi_type *ffi_type = ZEND_FFI_TYPE(cdata->type);
721+
zend_ffi_type *ffi_type = cdata->type;
722+
if (!ZEND_FFI_TYPE_IS_OWNED(ffi_type)) {
723723
if (ffi_type->attr & ZEND_FFI_ATTR_PERSISTENT) {
724724
op1_ffi_type = ffi_type;
725725
}
726+
} else {
727+
ffi_type = ZEND_FFI_TYPE(ffi_type);
728+
if (ffi_type->kind == ZEND_FFI_TYPE_POINTER) {
729+
ffi_type = ffi_type->pointer.type;
730+
if (!ZEND_FFI_TYPE_IS_OWNED(ffi_type)) {
731+
if (ffi_type->attr & ZEND_FFI_ATTR_PERSISTENT) {
732+
/* OWNED flag means POINTER TO */
733+
op1_ffi_type = ZEND_FFI_TYPE_MAKE_OWNED(ffi_type);
734+
}
735+
}
736+
}
726737
}
727738
} else if (ce1 == zend_ffi_ce) {
728739
zend_ffi *ffi = (zend_ffi*)Z_OBJ_P(zv);
@@ -783,11 +794,22 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
783794
#ifdef HAVE_FFI
784795
if (ce2 == zend_ffi_cdata_ce) {
785796
zend_ffi_cdata *cdata = (zend_ffi_cdata*)Z_OBJ_P(zv);
786-
if (!ZEND_FFI_TYPE_IS_OWNED(cdata->type)) {
787-
zend_ffi_type *ffi_type = ZEND_FFI_TYPE(cdata->type);
797+
zend_ffi_type *ffi_type = cdata->type;
798+
if (!ZEND_FFI_TYPE_IS_OWNED(ffi_type)) {
788799
if (ffi_type->attr & ZEND_FFI_ATTR_PERSISTENT) {
789800
op2_ffi_type = ffi_type;
790801
}
802+
} else {
803+
ffi_type = ZEND_FFI_TYPE(ffi_type);
804+
if (ffi_type->kind == ZEND_FFI_TYPE_POINTER) {
805+
ffi_type = ffi_type->pointer.type;
806+
if (!ZEND_FFI_TYPE_IS_OWNED(ffi_type)) {
807+
if (ffi_type->attr & ZEND_FFI_ATTR_PERSISTENT) {
808+
/* OWNED flag means POINTER TO */
809+
op2_ffi_type = ZEND_FFI_TYPE_MAKE_OWNED(ffi_type);
810+
}
811+
}
812+
}
791813
}
792814
}
793815
#endif
@@ -822,11 +844,22 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
822844
#ifdef HAVE_FFI
823845
if (ce3 == zend_ffi_cdata_ce) {
824846
zend_ffi_cdata *cdata = (zend_ffi_cdata*)Z_OBJ_P(zv);
825-
if (!ZEND_FFI_TYPE_IS_OWNED(cdata->type)) {
826-
zend_ffi_type *ffi_type = ZEND_FFI_TYPE(cdata->type);
847+
zend_ffi_type *ffi_type = cdata->type;
848+
if (!ZEND_FFI_TYPE_IS_OWNED(ffi_type)) {
827849
if (ffi_type->attr & ZEND_FFI_ATTR_PERSISTENT) {
828850
op3_ffi_type = ffi_type;
829851
}
852+
} else {
853+
ffi_type = ZEND_FFI_TYPE(ffi_type);
854+
if (ffi_type->kind == ZEND_FFI_TYPE_POINTER) {
855+
ffi_type = ffi_type->pointer.type;
856+
if (!ZEND_FFI_TYPE_IS_OWNED(ffi_type)) {
857+
if (ffi_type->attr & ZEND_FFI_ATTR_PERSISTENT) {
858+
/* OWNED flag means POINTER TO */
859+
op3_ffi_type = ZEND_FFI_TYPE_MAKE_OWNED(ffi_type);
860+
}
861+
}
862+
}
830863
}
831864
}
832865
#endif

0 commit comments

Comments
 (0)