@@ -12552,6 +12552,16 @@ static int zend_jit_ffi_read(zend_jit_ctx *jit,
12552
12552
res_type = IS_LONG;
12553
12553
break;
12554
12554
#endif
12555
+ case ZEND_FFI_TYPE_BOOL:
12556
+ jit_set_Z_TYPE_INFO(jit, res_addr,
12557
+ ir_ADD_U32(ir_ZEXT_U32(ir_LOAD_U8(ptr)), ir_CONST_U32(IS_FALSE)));
12558
+ return 1;
12559
+ case ZEND_FFI_TYPE_CHAR:
12560
+ jit_set_Z_PTR(jit, res_addr, ir_LOAD_A(
12561
+ ir_ADD_A(ir_CONST_ADDR(zend_one_char_string),
12562
+ ir_MUL_L(ir_ZEXT_L(ir_LOAD_U8(ptr)), ir_CONST_LONG(sizeof(void*))))));
12563
+ res_type = IS_STRING;
12564
+ break;
12555
12565
default:
12556
12566
ZEND_UNREACHABLE();
12557
12567
}
@@ -12606,6 +12616,11 @@ static int zend_jit_ffi_guard(zend_jit_ctx *jit,
12606
12616
return 1;
12607
12617
}
12608
12618
12619
+ static ir_ref jit_FFI_CDATA_PTR(zend_jit_ctx *jit, ir_ref obj_ref)
12620
+ {
12621
+ return ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
12622
+ }
12623
+
12609
12624
static int zend_jit_ffi_fetch_dim_read(zend_jit_ctx *jit,
12610
12625
const zend_op *opline,
12611
12626
zend_ssa *ssa,
@@ -12632,7 +12647,8 @@ static int zend_jit_ffi_fetch_dim_read(zend_jit_ctx *jit,
12632
12647
return 0;
12633
12648
}
12634
12649
12635
- ir_ref cdata_ref = ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
12650
+ ir_ref cdata_ref = jit_FFI_CDATA_PTR(jit, obj_ref);
12651
+ // ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
12636
12652
12637
12653
if (op1_ffi_type->kind == ZEND_FFI_TYPE_POINTER) {
12638
12654
cdata_ref = ir_LOAD_A(cdata_ref);
@@ -13318,14 +13334,17 @@ static int zend_jit_ffi_write(zend_jit_ctx *jit,
13318
13334
zend_ffi_type *ffi_type,
13319
13335
ir_ref ptr,
13320
13336
uint32_t val_info,
13321
- zend_jit_addr val_addr)
13337
+ zend_jit_addr val_addr,
13338
+ zend_ffi_type *val_ffi_type)
13322
13339
{
13323
13340
switch (ffi_type->kind) {
13324
13341
case ZEND_FFI_TYPE_FLOAT:
13325
13342
if (val_info == MAY_BE_LONG) {
13326
13343
ir_STORE(ptr, ir_INT2F(jit_Z_LVAL(jit, val_addr)));
13327
13344
} else if (val_info == MAY_BE_DOUBLE) {
13328
13345
ir_STORE(ptr, ir_D2F(jit_Z_DVAL(jit, val_addr)));
13346
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13347
+ ir_STORE(ptr, ir_LOAD_F(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13329
13348
} else {
13330
13349
ZEND_UNREACHABLE();
13331
13350
}
@@ -13335,34 +13354,57 @@ static int zend_jit_ffi_write(zend_jit_ctx *jit,
13335
13354
ir_STORE(ptr, ir_INT2D(jit_Z_LVAL(jit, val_addr)));
13336
13355
} else if (val_info == MAY_BE_DOUBLE) {
13337
13356
ir_STORE(ptr, jit_Z_DVAL(jit, val_addr));
13357
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13358
+ ir_STORE(ptr, ir_LOAD_D(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13338
13359
} else {
13339
13360
ZEND_UNREACHABLE();
13340
13361
}
13341
13362
break;
13363
+ case ZEND_FFI_TYPE_BOOL:
13364
+ if (val_info == MAY_BE_FALSE) {
13365
+ ir_STORE(ptr, IR_FALSE);
13366
+ return 1;
13367
+ } else if (val_info == MAY_BE_TRUE) {
13368
+ ir_STORE(ptr, IR_TRUE);
13369
+ return 1;
13370
+ } else if (val_info == (MAY_BE_FALSE|MAY_BE_TRUE)) {
13371
+ ir_STORE(ptr, ir_SUB_U8(jit_Z_TYPE(jit, val_addr), ir_CONST_U8(IS_FALSE)));
13372
+ return 1;
13373
+ }
13374
+ ZEND_FALLTHROUGH;
13342
13375
case ZEND_FFI_TYPE_UINT8:
13343
13376
if (val_info == MAY_BE_LONG) {
13344
13377
ir_STORE(ptr, ir_TRUNC_U8(jit_Z_LVAL(jit, val_addr)));
13378
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13379
+ ir_STORE(ptr, ir_LOAD_U8(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13345
13380
} else {
13346
13381
ZEND_UNREACHABLE();
13347
13382
}
13348
13383
break;
13349
13384
case ZEND_FFI_TYPE_SINT8:
13385
+ case ZEND_FFI_TYPE_CHAR:
13350
13386
if (val_info == MAY_BE_LONG) {
13351
13387
ir_STORE(ptr, ir_TRUNC_I8(jit_Z_LVAL(jit, val_addr)));
13388
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13389
+ ir_STORE(ptr, ir_LOAD_I8(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13352
13390
} else {
13353
13391
ZEND_UNREACHABLE();
13354
13392
}
13355
13393
break;
13356
13394
case ZEND_FFI_TYPE_UINT16:
13357
13395
if (val_info == MAY_BE_LONG) {
13358
13396
ir_STORE(ptr, ir_TRUNC_U16(jit_Z_LVAL(jit, val_addr)));
13397
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13398
+ ir_STORE(ptr, ir_LOAD_U16(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13359
13399
} else {
13360
13400
ZEND_UNREACHABLE();
13361
13401
}
13362
13402
break;
13363
13403
case ZEND_FFI_TYPE_SINT16:
13364
13404
if (val_info == MAY_BE_LONG) {
13365
13405
ir_STORE(ptr, ir_TRUNC_I16(jit_Z_LVAL(jit, val_addr)));
13406
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13407
+ ir_STORE(ptr, ir_LOAD_I16(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13366
13408
} else {
13367
13409
ZEND_UNREACHABLE();
13368
13410
}
@@ -13371,13 +13413,17 @@ static int zend_jit_ffi_write(zend_jit_ctx *jit,
13371
13413
case ZEND_FFI_TYPE_UINT32:
13372
13414
if (val_info == MAY_BE_LONG) {
13373
13415
ir_STORE(ptr, ir_TRUNC_U32(jit_Z_LVAL(jit, val_addr)));
13416
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13417
+ ir_STORE(ptr, ir_LOAD_U32(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13374
13418
} else {
13375
13419
ZEND_UNREACHABLE();
13376
13420
}
13377
13421
break;
13378
13422
case ZEND_FFI_TYPE_SINT32:
13379
13423
if (val_info == MAY_BE_LONG) {
13380
13424
ir_STORE(ptr, ir_TRUNC_I32(jit_Z_LVAL(jit, val_addr)));
13425
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13426
+ ir_STORE(ptr, ir_LOAD_I32(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13381
13427
} else {
13382
13428
ZEND_UNREACHABLE();
13383
13429
}
@@ -13386,6 +13432,8 @@ static int zend_jit_ffi_write(zend_jit_ctx *jit,
13386
13432
case ZEND_FFI_TYPE_SINT64:
13387
13433
if (val_info == MAY_BE_LONG) {
13388
13434
ir_STORE(ptr, jit_Z_LVAL(jit, val_addr));
13435
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13436
+ ir_STORE(ptr, ir_LOAD_I64(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13389
13437
} else {
13390
13438
ZEND_UNREACHABLE();
13391
13439
}
@@ -13395,6 +13443,8 @@ static int zend_jit_ffi_write(zend_jit_ctx *jit,
13395
13443
case ZEND_FFI_TYPE_SINT32:
13396
13444
if (val_info == MAY_BE_LONG) {
13397
13445
ir_STORE(ptr, jit_Z_LVAL(jit, val_addr));
13446
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13447
+ ir_STORE(ptr, ir_LOAD_I32(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13398
13448
} else {
13399
13449
ZEND_UNREACHABLE();
13400
13450
}
@@ -13421,6 +13471,7 @@ static int zend_jit_ffi_assign_dim(zend_jit_ctx *jit,
13421
13471
zend_jit_addr val_def_addr,
13422
13472
zend_jit_addr res_addr,
13423
13473
zend_ffi_type *op1_ffi_type,
13474
+ zend_ffi_type *val_ffi_type,
13424
13475
zend_jit_ffi_info *ffi_info)
13425
13476
{
13426
13477
zend_ffi_type *el_type = ZEND_FFI_TYPE(op1_ffi_type->array.type);
@@ -13442,7 +13493,7 @@ static int zend_jit_ffi_assign_dim(zend_jit_ctx *jit,
13442
13493
13443
13494
ir_ref ptr = ir_ADD_A(cdata_ref, ir_MUL_L(jit_Z_LVAL(jit, op2_addr), ir_CONST_LONG(el_type->size)));
13444
13495
13445
- if (!zend_jit_ffi_write(jit, el_type, ptr, val_info, val_addr)) {
13496
+ if (!zend_jit_ffi_write(jit, el_type, ptr, val_info, val_addr, val_ffi_type )) {
13446
13497
return 0;
13447
13498
}
13448
13499
@@ -13736,6 +13787,16 @@ static int zend_jit_ffi_assign_op_helper(zend_jit_ctx *jit,
13736
13787
return 0;
13737
13788
}
13738
13789
break;
13790
+ case ZEND_FFI_TYPE_BOOL:
13791
+ type = IR_U8;
13792
+ ZEND_ASSERT(opcode == ZEND_BW_AND || opcode == ZEND_BW_OR);
13793
+ if (op2_info == MAY_BE_LONG) {
13794
+ op2 = ir_TRUNC_U8(jit_Z_LVAL(jit, op2_addr));
13795
+ } else {
13796
+ ZEND_UNREACHABLE();
13797
+ return 0;
13798
+ }
13799
+ break;
13739
13800
case ZEND_FFI_TYPE_UINT8:
13740
13801
type = IR_U8;
13741
13802
if (op2_info == MAY_BE_LONG) {
@@ -13746,6 +13807,7 @@ static int zend_jit_ffi_assign_op_helper(zend_jit_ctx *jit,
13746
13807
}
13747
13808
break;
13748
13809
case ZEND_FFI_TYPE_SINT8:
13810
+ case ZEND_FFI_TYPE_CHAR:
13749
13811
type = IR_I8;
13750
13812
if (op2_info == MAY_BE_LONG) {
13751
13813
op2 = ir_TRUNC_I8(jit_Z_LVAL(jit, op2_addr));
@@ -14872,6 +14934,7 @@ static int zend_jit_ffi_assign_obj(zend_jit_ctx *jit,
14872
14934
zend_jit_addr val_def_addr,
14873
14935
zend_jit_addr res_addr,
14874
14936
zend_ffi_type *op1_ffi_type,
14937
+ zend_ffi_type *val_ffi_type,
14875
14938
zend_jit_ffi_info *ffi_info)
14876
14939
{
14877
14940
zend_ffi_type *field_type = ZEND_FFI_TYPE(field->type);
@@ -14884,7 +14947,7 @@ static int zend_jit_ffi_assign_obj(zend_jit_ctx *jit,
14884
14947
ir_ref cdata_ref = ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
14885
14948
ir_ref ptr = ir_ADD_A(cdata_ref, ir_CONST_LONG(field->offset));
14886
14949
14887
- if (!zend_jit_ffi_write(jit, field_type, ptr, val_info, val_addr)) {
14950
+ if (!zend_jit_ffi_write(jit, field_type, ptr, val_info, val_addr, val_ffi_type )) {
14888
14951
return 0;
14889
14952
}
14890
14953
@@ -17567,13 +17630,10 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa
17567
17630
zend_ffi_type *op1_ffi_type = (zend_ffi_type*)(trace+2)->ptr;
17568
17631
if (op1_ffi_type
17569
17632
&& (op1_ffi_type->kind == ZEND_FFI_TYPE_ARRAY || op1_ffi_type->kind == ZEND_FFI_TYPE_POINTER)
17570
- && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind >= ZEND_FFI_TYPE_FLOAT
17571
- && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind <= ZEND_FFI_TYPE_ENUM
17572
- #if defined(IR_TARGET_X86)
17573
- && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind != ZEND_FFI_TYPE_UINT64
17574
- && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind != ZEND_FFI_TYPE_SINT64
17575
- #endif
17576
- && op2_info == MAY_BE_LONG) {
17633
+ && op2_info == MAY_BE_LONG
17634
+ && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind < ZEND_FFI_TYPE_POINTER
17635
+ && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind != ZEND_FFI_TYPE_VOID
17636
+ && zend_jit_ffi_supported_type(ZEND_FFI_TYPE(op1_ffi_type->array.type))) {
17577
17637
return 1;
17578
17638
}
17579
17639
}
@@ -17629,20 +17689,19 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa
17629
17689
&& (trace+1)->op == ZEND_JIT_TRACE_OP1_TYPE
17630
17690
&& (trace+2)->op == ZEND_JIT_TRACE_OP1_FFI_TYPE) {
17631
17691
zend_ffi_type *op1_ffi_type = (zend_ffi_type*)(trace+2)->ptr;
17692
+ zend_ffi_type *op3_ffi_type = NULL;
17693
+ uint32_t op1_data_info = OP1_DATA_INFO();
17694
+
17695
+ if ((trace+3)->op == ZEND_JIT_TRACE_OP3_TYPE
17696
+ && (trace+4)->op == ZEND_JIT_TRACE_OP3_FFI_TYPE) {
17697
+ op3_ffi_type = (zend_ffi_type*)(trace+4)->ptr;
17698
+ }
17699
+
17632
17700
if (op1_ffi_type
17633
17701
&& (op1_ffi_type->kind == ZEND_FFI_TYPE_ARRAY || op1_ffi_type->kind == ZEND_FFI_TYPE_POINTER)
17634
- && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind >= ZEND_FFI_TYPE_FLOAT
17635
- && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind <= ZEND_FFI_TYPE_ENUM
17636
- #if defined(IR_TARGET_X86)
17637
- && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind != ZEND_FFI_TYPE_UINT64
17638
- && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind != ZEND_FFI_TYPE_SINT64
17639
- #endif
17640
- && op2_info == MAY_BE_LONG) {
17641
- uint32_t op1_data_info = OP1_DATA_INFO();
17642
-
17643
- if (op1_data_info == MAY_BE_LONG || op1_data_info == MAY_BE_DOUBLE) {
17644
- return 1;
17645
- }
17702
+ && op2_info == MAY_BE_LONG
17703
+ && zend_jit_ffi_compatible(op1_ffi_type->array.type, op1_data_info, op3_ffi_type)) {
17704
+ return 1;
17646
17705
}
17647
17706
}
17648
17707
#endif
0 commit comments