Skip to content

Commit 49f86a7

Browse files
committed
Add class abd FFI type guards
1 parent e0ee9f2 commit 49f86a7

File tree

2 files changed

+108
-32
lines changed

2 files changed

+108
-32
lines changed

ext/opcache/jit/zend_jit_ir.c

Lines changed: 106 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -12426,6 +12426,23 @@ static int zend_jit_fetch_dim_read(zend_jit_ctx *jit,
1242612426
}
1242712427

1242812428
#ifdef HAVE_FFI
12429+
static int zend_jit_class_guard(zend_jit_ctx *jit, const zend_op *opline, ir_ref obj_ref, zend_class_entry *ce);
12430+
12431+
static int zend_jit_ffi_type_guard(zend_jit_ctx *jit, const zend_op *opline, ir_ref obj_ref, zend_ffi_type *ffi_type)
12432+
{
12433+
int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0);
12434+
const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
12435+
12436+
if (!exit_addr) {
12437+
return 0;
12438+
}
12439+
12440+
ir_GUARD(ir_EQ(ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, type))), ir_CONST_ADDR(ffi_type)),
12441+
ir_CONST_ADDR(exit_addr));
12442+
12443+
return 1;
12444+
}
12445+
1242912446
static int zend_jit_ffi_abc(zend_jit_ctx *jit,
1243012447
const zend_op *opline,
1243112448
zend_ffi_type *ffi_type,
@@ -12492,15 +12509,30 @@ static int zend_jit_ffi_fetch_dim_read(zend_jit_ctx *jit,
1249212509
{
1249312510
uint32_t res_type;
1249412511
zend_ffi_type *el_type = ZEND_FFI_TYPE(op1_ffi_type->array.type);
12512+
ir_ref obj_ref = jit_Z_PTR(jit, op1_addr);
12513+
12514+
if (ssa->var_info
12515+
&& ssa_op->op1_use >= 0
12516+
&& ssa->var_info[ssa_op->op1_use].ce != zend_ffi_cdata_ce) {
12517+
if (!zend_jit_class_guard(jit, opline, obj_ref, zend_ffi_cdata_ce)) {
12518+
return 0;
12519+
}
12520+
if (ssa->var_info && ssa_op->op1_use >= 0) {
12521+
ssa->var_info[ssa_op->op1_use].type |= MAY_BE_CLASS_GUARD;
12522+
ssa->var_info[ssa_op->op1_use].ce = zend_ffi_cdata_ce;
12523+
ssa->var_info[ssa_op->op1_use].is_instanceof = 0;
12524+
}
12525+
}
1249512526

12496-
// TODO: ce guard ???
1249712527
// TODO: ffi type guard ???
12528+
if (!zend_jit_ffi_type_guard(jit, opline, obj_ref, op1_ffi_type)) {
12529+
return 0;
12530+
}
1249812531

1249912532
if (!zend_jit_ffi_abc(jit, opline, op1_ffi_type, op2_info, op2_addr, op2_range)) {
1250012533
return 0;
1250112534
}
1250212535

12503-
ir_ref obj_ref = jit_Z_PTR(jit, op1_addr);
1250412536
ir_ref cdata_ref = ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
1250512537

1250612538
if (op1_ffi_type->kind == ZEND_FFI_TYPE_POINTER) {
@@ -13238,29 +13270,51 @@ static int zend_jit_assign_dim(zend_jit_ctx *jit,
1323813270
}
1323913271

1324013272
#ifdef HAVE_FFI
13241-
static int zend_jit_ffi_assign_dim(zend_jit_ctx *jit,
13242-
const zend_op *opline,
13243-
uint32_t op1_info,
13244-
zend_jit_addr op1_addr,
13245-
uint32_t op2_info,
13246-
zend_jit_addr op2_addr,
13247-
zend_ssa_range *op2_range,
13248-
uint32_t val_info,
13249-
zend_jit_addr op3_addr,
13250-
zend_jit_addr op3_def_addr,
13251-
zend_jit_addr res_addr,
13252-
zend_ffi_type *op1_ffi_type)
13273+
static int zend_jit_ffi_assign_dim(zend_jit_ctx *jit,
13274+
const zend_op *opline,
13275+
zend_ssa *ssa,
13276+
const zend_ssa_op *ssa_op,
13277+
uint32_t op1_info,
13278+
zend_jit_addr op1_addr,
13279+
uint32_t op2_info,
13280+
zend_jit_addr op2_addr,
13281+
zend_ssa_range *op2_range,
13282+
uint32_t val_info,
13283+
zend_jit_addr op3_addr,
13284+
zend_jit_addr op3_def_addr,
13285+
zend_jit_addr res_addr,
13286+
zend_ffi_type *op1_ffi_type)
1325313287
{
1325413288
zend_ffi_type *el_type = ZEND_FFI_TYPE(op1_ffi_type->array.type);
13289+
ir_ref obj_ref = jit_Z_PTR(jit, op1_addr);
13290+
13291+
if (ssa->var_info
13292+
&& ssa_op->op1_use >= 0
13293+
&& ssa->var_info[ssa_op->op1_use].ce != zend_ffi_cdata_ce) {
13294+
if (!zend_jit_class_guard(jit, opline, obj_ref, zend_ffi_cdata_ce)) {
13295+
return 0;
13296+
}
13297+
if (ssa->var_info && ssa_op->op1_use >= 0) {
13298+
ssa->var_info[ssa_op->op1_use].type |= MAY_BE_CLASS_GUARD;
13299+
ssa->var_info[ssa_op->op1_use].ce = zend_ffi_cdata_ce;
13300+
ssa->var_info[ssa_op->op1_use].is_instanceof = 0;
13301+
}
13302+
if (ssa->var_info && ssa_op->op1_def >= 0) {
13303+
ssa->var_info[ssa_op->op1_def].type |= MAY_BE_CLASS_GUARD;
13304+
ssa->var_info[ssa_op->op1_def].ce = zend_ffi_cdata_ce;
13305+
ssa->var_info[ssa_op->op1_def].is_instanceof = 0;
13306+
}
13307+
}
1325513308

13256-
// TODO: ce guard ???
1325713309
// TODO: ffi type guard ???
13310+
if (!zend_jit_ffi_type_guard(jit, opline, obj_ref, op1_ffi_type)) {
13311+
return 0;
13312+
}
1325813313

1325913314
if (!zend_jit_ffi_abc(jit, opline, op1_ffi_type, op2_info, op2_addr, op2_range)) {
1326013315
return 0;
1326113316
}
1326213317

13263-
ir_ref obj_ref = jit_Z_PTR(jit, op1_addr);
1326413318
ir_ref cdata_ref = ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
1326513319

1326613320
if (op1_ffi_type->kind == ZEND_FFI_TYPE_POINTER) {
@@ -13730,29 +13784,51 @@ static int zend_jit_ffi_assign_op_helper(zend_jit_ctx *jit,
1373013784
return 1;
1373113785
}
1373213786

13733-
static int zend_jit_ffi_assign_dim_op(zend_jit_ctx *jit,
13734-
const zend_op *opline,
13735-
uint32_t op1_info,
13736-
uint32_t op1_def_info,
13737-
zend_jit_addr op1_addr,
13738-
uint32_t op2_info,
13739-
zend_jit_addr op2_addr,
13740-
zend_ssa_range *op2_range,
13741-
uint32_t op1_data_info,
13742-
zend_jit_addr op3_addr,
13743-
zend_ssa_range *op1_data_range,
13744-
zend_ffi_type *op1_ffi_type)
13787+
static int zend_jit_ffi_assign_dim_op(zend_jit_ctx *jit,
13788+
const zend_op *opline,
13789+
zend_ssa *ssa,
13790+
const zend_ssa_op *ssa_op,
13791+
uint32_t op1_info,
13792+
uint32_t op1_def_info,
13793+
zend_jit_addr op1_addr,
13794+
uint32_t op2_info,
13795+
zend_jit_addr op2_addr,
13796+
zend_ssa_range *op2_range,
13797+
uint32_t op1_data_info,
13798+
zend_jit_addr op3_addr,
13799+
zend_ssa_range *op1_data_range,
13800+
zend_ffi_type *op1_ffi_type)
1374513801
{
1374613802
zend_ffi_type *el_type = ZEND_FFI_TYPE(op1_ffi_type->array.type);
13803+
ir_ref obj_ref = jit_Z_PTR(jit, op1_addr);
13804+
13805+
if (ssa->var_info
13806+
&& ssa_op->op1_use >= 0
13807+
&& ssa->var_info[ssa_op->op1_use].ce != zend_ffi_cdata_ce) {
13808+
if (!zend_jit_class_guard(jit, opline, obj_ref, zend_ffi_cdata_ce)) {
13809+
return 0;
13810+
}
13811+
if (ssa->var_info && ssa_op->op1_use >= 0) {
13812+
ssa->var_info[ssa_op->op1_use].type |= MAY_BE_CLASS_GUARD;
13813+
ssa->var_info[ssa_op->op1_use].ce = zend_ffi_cdata_ce;
13814+
ssa->var_info[ssa_op->op1_use].is_instanceof = 0;
13815+
}
13816+
if (ssa->var_info && ssa_op->op1_def >= 0) {
13817+
ssa->var_info[ssa_op->op1_def].type |= MAY_BE_CLASS_GUARD;
13818+
ssa->var_info[ssa_op->op1_def].ce = zend_ffi_cdata_ce;
13819+
ssa->var_info[ssa_op->op1_def].is_instanceof = 0;
13820+
}
13821+
}
1374713822

13748-
// TODO: ce guard ???
1374913823
// TODO: ffi type guard ???
13824+
if (!zend_jit_ffi_type_guard(jit, opline, obj_ref, op1_ffi_type)) {
13825+
return 0;
13826+
}
1375013827

1375113828
if (!zend_jit_ffi_abc(jit, opline, op1_ffi_type, op2_info, op2_addr, op2_range)) {
1375213829
return 0;
1375313830
}
1375413831

13755-
ir_ref obj_ref = jit_Z_PTR(jit, op1_addr);
1375613832
ir_ref cdata_ref = ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
1375713833

1375813834
if (op1_ffi_type->kind == ZEND_FFI_TYPE_POINTER) {

ext/opcache/jit/zend_jit_trace.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4691,7 +4691,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
46914691
&& ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind >= ZEND_FFI_TYPE_FLOAT
46924692
&& ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind <= ZEND_FFI_TYPE_ENUM
46934693
&& op2_info == MAY_BE_LONG) {
4694-
if (!zend_jit_ffi_assign_dim_op(&ctx, opline,
4694+
if (!zend_jit_ffi_assign_dim_op(&ctx, opline, ssa, ssa_op,
46954695
op1_info, op1_def_info, op1_addr,
46964696
op2_info, (opline->op2_type != IS_UNUSED) ? OP2_REG_ADDR() : 0,
46974697
(opline->op2_type != IS_UNUSED) ? OP2_RANGE() : NULL,
@@ -5024,7 +5024,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
50245024
&& ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind >= ZEND_FFI_TYPE_FLOAT
50255025
&& ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind <= ZEND_FFI_TYPE_ENUM
50265026
&& op2_info == MAY_BE_LONG) {
5027-
if (!zend_jit_ffi_assign_dim(&ctx, opline,
5027+
if (!zend_jit_ffi_assign_dim(&ctx, opline, ssa, ssa_op,
50285028
op1_info, op1_addr,
50295029
op2_info, (opline->op2_type != IS_UNUSED) ? OP2_REG_ADDR() : 0,
50305030
(opline->op2_type != IS_UNUSED) ? OP2_RANGE() : NULL,

0 commit comments

Comments
 (0)