Skip to content

Commit 2e24b19

Browse files
committed
JIT to read FFI variables
1 parent 78beca0 commit 2e24b19

File tree

8 files changed

+87
-9
lines changed

8 files changed

+87
-9
lines changed

Zend/zend.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ ZEND_API void (*zend_post_shutdown_cb)(void) = NULL;
9797
ZEND_ATTRIBUTE_NONNULL ZEND_API zend_result (*zend_random_bytes)(void *bytes, size_t size, char *errstr, size_t errstr_size) = NULL;
9898
ZEND_ATTRIBUTE_NONNULL ZEND_API void (*zend_random_bytes_insecure)(zend_random_bytes_insecure_state *state, void *bytes, size_t size) = NULL;
9999

100+
ZEND_API zend_class_entry *zend_ffi_ce = NULL;
100101
ZEND_API zend_class_entry *zend_ffi_cdata_ce = NULL;
101102
ZEND_API zend_ffi_dcl* (*zend_ffi_cache_type_get)(zend_string *str) = NULL;
102103
ZEND_API zend_ffi_dcl* (*zend_ffi_cache_type_add)(zend_string *str, zend_ffi_dcl *dcl) = NULL;

Zend/zend.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ extern ZEND_API zend_class_entry *zend_standard_class_def;
389389
extern ZEND_API zend_utility_values zend_uv;
390390

391391
/* FFI/OPCache interopability API */
392+
extern ZEND_API zend_class_entry *zend_ffi_ce;
392393
extern ZEND_API zend_class_entry *zend_ffi_cdata_ce;
393394

394395
typedef struct _zend_ffi_dcl zend_ffi_dcl;

ext/ffi/ffi.c

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

6565
#include "ffi_arginfo.h"
6666

67-
typedef struct _zend_ffi {
68-
zend_object std;
69-
DL_HANDLE lib;
70-
HashTable *symbols;
71-
HashTable *tags;
72-
bool persistent;
73-
} zend_ffi;
74-
7567
#define ZEND_FFI_TYPE_MAKE_OWNED(t) \
7668
((zend_ffi_type*)(((uintptr_t)(t)) | ZEND_FFI_TYPE_OWNED))
7769

@@ -80,7 +72,6 @@ typedef struct _zend_ffi {
8072

8173
static zend_class_entry *zend_ffi_exception_ce;
8274
static zend_class_entry *zend_ffi_parser_exception_ce;
83-
static zend_class_entry *zend_ffi_ce;
8475
static zend_class_entry *zend_ffi_ctype_ce;
8576

8677
static zend_object_handlers zend_ffi_handlers;

ext/ffi/php_ffi.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,14 @@ typedef struct _zend_ffi_scope {
393393
HashTable *tags;
394394
} zend_ffi_scope;
395395

396+
typedef struct _zend_ffi {
397+
zend_object std;
398+
DL_HANDLE lib;
399+
HashTable *symbols;
400+
HashTable *tags;
401+
bool persistent;
402+
} zend_ffi;
403+
396404
#define ZEND_FFI_TYPE_OWNED (1<<0)
397405

398406
#define ZEND_FFI_TYPE(t) \

ext/opcache/jit/zend_jit_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ typedef enum _zend_jit_trace_op {
349349
ZEND_JIT_TRACE_OP1_FFI_TYPE,
350350
ZEND_JIT_TRACE_OP2_FFI_TYPE,
351351
ZEND_JIT_TRACE_OP3_FFI_TYPE,
352+
ZEND_JIT_TRACE_OP1_FFI_SYMBOLS,
352353
ZEND_JIT_TRACE_VAL_INFO,
353354
ZEND_JIT_TRACE_INIT_CALL,
354355
ZEND_JIT_TRACE_DO_ICALL,

ext/opcache/jit/zend_jit_ir.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14422,6 +14422,49 @@ static int zend_jit_ffi_fetch_obj(zend_jit_ctx *jit,
1442214422

1442314423
return 1;
1442414424
}
14425+
14426+
static int zend_jit_ffi_fetch_sym(zend_jit_ctx *jit,
14427+
const zend_op *opline,
14428+
const zend_op_array *op_array,
14429+
zend_ssa *ssa,
14430+
const zend_ssa_op *ssa_op,
14431+
uint32_t op1_info,
14432+
zend_jit_addr op1_addr,
14433+
bool op1_indirect,
14434+
bool on_this,
14435+
bool delayed_fetch_this,
14436+
bool op1_avoid_refcounting,
14437+
zend_ffi_symbol *sym,
14438+
zend_jit_addr res_addr/*???,
14439+
zend_ffi_type *op1_ffi_type,
14440+
zend_jit_ffi_info *ffi_info*/)
14441+
{
14442+
uint32_t res_info = RES_INFO();
14443+
zend_ffi_type *sym_type = ZEND_FFI_TYPE(sym->type);
14444+
//??? ir_ref obj_ref = jit_Z_PTR(jit, op1_addr);
14445+
14446+
//??? if (!zend_jit_ffi_guard(jit, opline, ssa, ssa_op->op1_use, -1, obj_ref, op1_ffi_type, ffi_info)) {
14447+
//??? return 0;
14448+
//??? }
14449+
14450+
ir_ref ptr = ir_CONST_ADDR(sym->addr);
14451+
if (!zend_jit_ffi_read(jit, sym_type, ptr, res_addr)) {
14452+
return 0;
14453+
}
14454+
14455+
if (res_info & MAY_BE_GUARD) {
14456+
// TODO: ???
14457+
ssa->var_info[ssa_op->result_def].type &= ~MAY_BE_GUARD;
14458+
}
14459+
14460+
if (!op1_avoid_refcounting) {
14461+
if (opline->op1_type & (IS_TMP_VAR|IS_VAR)) {
14462+
jit_FREE_OP(jit, opline->op1_type, opline->op1, op1_info, opline);
14463+
}
14464+
}
14465+
14466+
return 1;
14467+
}
1442514468
#endif
1442614469

1442714470
static int zend_jit_fetch_obj(zend_jit_ctx *jit,

ext/opcache/jit/zend_jit_trace.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4315,6 +4315,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
43154315
zend_ffi_type *op1_ffi_type = NULL;
43164316
zend_ffi_type *op2_ffi_type = NULL;
43174317
zend_ffi_type *op3_ffi_type = NULL;
4318+
HashTable *op1_ffi_symbols = NULL;
43184319
(void)op2_ffi_type;
43194320
#endif
43204321
bool gen_handler = false;
@@ -4341,6 +4342,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
43414342
if ((p+1)->op == ZEND_JIT_TRACE_OP1_FFI_TYPE) {
43424343
op1_ffi_type = (zend_ffi_type*)(p+1)->ptr;
43434344
p++;
4345+
} else if ((p+1)->op == ZEND_JIT_TRACE_OP1_FFI_SYMBOLS) {
4346+
op1_ffi_symbols = (HashTable*)(p+1)->ptr;
4347+
p++;
43444348
}
43454349
#endif
43464350
if ((p+1)->op == ZEND_JIT_TRACE_OP2_TYPE) {
@@ -6167,6 +6171,22 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
61676171
}
61686172
goto done;
61696173
}
6174+
} else if (opline->opcode == ZEND_FETCH_OBJ_R && op1_ffi_symbols) {
6175+
zend_ffi_symbol *sym = zend_hash_find_ptr(op1_ffi_symbols,
6176+
Z_STR_P(RT_CONSTANT(opline, opline->op2)));
6177+
if (sym
6178+
&& (sym->kind == ZEND_FFI_SYM_VAR || sym->kind == ZEND_FFI_SYM_CONST)
6179+
&& ZEND_FFI_TYPE(sym->type)->kind < ZEND_FFI_TYPE_POINTER
6180+
&& ZEND_FFI_TYPE(sym->type)->kind != ZEND_FFI_TYPE_VOID
6181+
&& zend_jit_ffi_supported_type(ZEND_FFI_TYPE(sym->type))) {
6182+
if (!zend_jit_ffi_fetch_sym(&ctx, opline, op_array, ssa, ssa_op,
6183+
op1_info, op1_addr, op1_indirect,
6184+
on_this, delayed_fetch_this, avoid_refcounting, sym,
6185+
RES_REG_ADDR())) {
6186+
goto jit_failure;
6187+
}
6188+
goto done;
6189+
}
61706190
}
61716191
#endif
61726192
if (!zend_jit_fetch_obj(&ctx, opline, op_array, ssa, ssa_op,
@@ -7870,6 +7890,10 @@ static void zend_jit_dump_trace(zend_jit_trace_rec *trace_buffer, zend_ssa *tssa
78707890
fprintf(stderr, " op1(%sobject of class %s: ffi_type)", ref,
78717891
ZSTR_VAL(p->ce->name));
78727892
p++;
7893+
} else if ((p+1)->op == ZEND_JIT_TRACE_OP1_FFI_SYMBOLS) {
7894+
fprintf(stderr, " op1(%sobject of class %s: ffi_symbols)", ref,
7895+
ZSTR_VAL(p->ce->name));
7896+
p++;
78737897
} else
78747898
#endif
78757899
fprintf(stderr, " op1(%sobject of class %s)", ref,

ext/opcache/jit/zend_jit_vm_helpers.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
599599
zend_class_entry *ce1, *ce2, *ce3;
600600
#ifdef HAVE_FFI
601601
zend_ffi_type *op1_ffi_type, *op2_ffi_type, *op3_ffi_type;
602+
HashTable *op1_ffi_symbols;
602603
#endif
603604
const zend_op *link_to_enter_opline = NULL;
604605
int backtrack_link_to_enter = -1;
@@ -672,6 +673,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
672673
ce1 = ce2 = ce3 = NULL;
673674
#ifdef HAVE_FFI
674675
op1_ffi_type = op2_ffi_type = op3_ffi_type = NULL;
676+
op1_ffi_symbols = NULL;
675677
#endif
676678
op1_type = op2_type = op3_type = IS_UNKNOWN;
677679
if ((opline->op1_type & (IS_TMP_VAR|IS_VAR|IS_CV))
@@ -705,6 +707,11 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
705707
op1_ffi_type = ffi_type;
706708
}
707709
}
710+
} else if (ce1 == zend_ffi_ce) {
711+
zend_ffi *ffi = (zend_ffi*)Z_OBJ_P(zv);
712+
if (ffi->persistent && ffi->symbols) {
713+
op1_ffi_symbols = ffi->symbols;
714+
}
708715
}
709716
#endif
710717
} else if (Z_TYPE_P(zv) == IS_ARRAY) {
@@ -818,6 +825,8 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
818825
#ifdef HAVE_FFI
819826
if (op1_ffi_type) {
820827
TRACE_RECORD(ZEND_JIT_TRACE_OP1_FFI_TYPE, 0, op1_ffi_type);
828+
} else if (op1_ffi_symbols) {
829+
TRACE_RECORD(ZEND_JIT_TRACE_OP1_FFI_SYMBOLS, 0, op1_ffi_symbols);
821830
}
822831
#endif
823832
}

0 commit comments

Comments
 (0)