@@ -12595,6 +12595,16 @@ static int zend_jit_ffi_read(zend_jit_ctx *jit,
12595
12595
res_type = IS_LONG;
12596
12596
break;
12597
12597
#endif
12598
+ case ZEND_FFI_TYPE_BOOL:
12599
+ jit_set_Z_TYPE_INFO(jit, res_addr,
12600
+ ir_ADD_U32(ir_ZEXT_U32(ir_LOAD_U8(ptr)), ir_CONST_U32(IS_FALSE)));
12601
+ return 1;
12602
+ case ZEND_FFI_TYPE_CHAR:
12603
+ jit_set_Z_PTR(jit, res_addr, ir_LOAD_A(
12604
+ ir_ADD_A(ir_CONST_ADDR(zend_one_char_string),
12605
+ ir_MUL_L(ir_ZEXT_L(ir_LOAD_U8(ptr)), ir_CONST_LONG(sizeof(void*))))));
12606
+ res_type = IS_STRING;
12607
+ break;
12598
12608
default:
12599
12609
ZEND_UNREACHABLE();
12600
12610
}
@@ -12649,6 +12659,11 @@ static int zend_jit_ffi_guard(zend_jit_ctx *jit,
12649
12659
return 1;
12650
12660
}
12651
12661
12662
+ static ir_ref jit_FFI_CDATA_PTR(zend_jit_ctx *jit, ir_ref obj_ref)
12663
+ {
12664
+ return ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
12665
+ }
12666
+
12652
12667
static int zend_jit_ffi_fetch_dim_read(zend_jit_ctx *jit,
12653
12668
const zend_op *opline,
12654
12669
zend_ssa *ssa,
@@ -12675,7 +12690,8 @@ static int zend_jit_ffi_fetch_dim_read(zend_jit_ctx *jit,
12675
12690
return 0;
12676
12691
}
12677
12692
12678
- ir_ref cdata_ref = ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
12693
+ ir_ref cdata_ref = jit_FFI_CDATA_PTR(jit, obj_ref);
12694
+ // ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
12679
12695
12680
12696
if (op1_ffi_type->kind == ZEND_FFI_TYPE_POINTER) {
12681
12697
cdata_ref = ir_LOAD_A(cdata_ref);
@@ -13361,14 +13377,17 @@ static int zend_jit_ffi_write(zend_jit_ctx *jit,
13361
13377
zend_ffi_type *ffi_type,
13362
13378
ir_ref ptr,
13363
13379
uint32_t val_info,
13364
- zend_jit_addr val_addr)
13380
+ zend_jit_addr val_addr,
13381
+ zend_ffi_type *val_ffi_type)
13365
13382
{
13366
13383
switch (ffi_type->kind) {
13367
13384
case ZEND_FFI_TYPE_FLOAT:
13368
13385
if (val_info == MAY_BE_LONG) {
13369
13386
ir_STORE(ptr, ir_INT2F(jit_Z_LVAL(jit, val_addr)));
13370
13387
} else if (val_info == MAY_BE_DOUBLE) {
13371
13388
ir_STORE(ptr, ir_D2F(jit_Z_DVAL(jit, val_addr)));
13389
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13390
+ ir_STORE(ptr, ir_LOAD_F(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13372
13391
} else {
13373
13392
ZEND_UNREACHABLE();
13374
13393
}
@@ -13378,34 +13397,57 @@ static int zend_jit_ffi_write(zend_jit_ctx *jit,
13378
13397
ir_STORE(ptr, ir_INT2D(jit_Z_LVAL(jit, val_addr)));
13379
13398
} else if (val_info == MAY_BE_DOUBLE) {
13380
13399
ir_STORE(ptr, jit_Z_DVAL(jit, val_addr));
13400
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13401
+ ir_STORE(ptr, ir_LOAD_D(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13381
13402
} else {
13382
13403
ZEND_UNREACHABLE();
13383
13404
}
13384
13405
break;
13406
+ case ZEND_FFI_TYPE_BOOL:
13407
+ if (val_info == MAY_BE_FALSE) {
13408
+ ir_STORE(ptr, IR_FALSE);
13409
+ return 1;
13410
+ } else if (val_info == MAY_BE_TRUE) {
13411
+ ir_STORE(ptr, IR_TRUE);
13412
+ return 1;
13413
+ } else if (val_info == (MAY_BE_FALSE|MAY_BE_TRUE)) {
13414
+ ir_STORE(ptr, ir_SUB_U8(jit_Z_TYPE(jit, val_addr), ir_CONST_U8(IS_FALSE)));
13415
+ return 1;
13416
+ }
13417
+ ZEND_FALLTHROUGH;
13385
13418
case ZEND_FFI_TYPE_UINT8:
13386
13419
if (val_info == MAY_BE_LONG) {
13387
13420
ir_STORE(ptr, ir_TRUNC_U8(jit_Z_LVAL(jit, val_addr)));
13421
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13422
+ ir_STORE(ptr, ir_LOAD_U8(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13388
13423
} else {
13389
13424
ZEND_UNREACHABLE();
13390
13425
}
13391
13426
break;
13392
13427
case ZEND_FFI_TYPE_SINT8:
13428
+ case ZEND_FFI_TYPE_CHAR:
13393
13429
if (val_info == MAY_BE_LONG) {
13394
13430
ir_STORE(ptr, ir_TRUNC_I8(jit_Z_LVAL(jit, val_addr)));
13431
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13432
+ ir_STORE(ptr, ir_LOAD_I8(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13395
13433
} else {
13396
13434
ZEND_UNREACHABLE();
13397
13435
}
13398
13436
break;
13399
13437
case ZEND_FFI_TYPE_UINT16:
13400
13438
if (val_info == MAY_BE_LONG) {
13401
13439
ir_STORE(ptr, ir_TRUNC_U16(jit_Z_LVAL(jit, val_addr)));
13440
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13441
+ ir_STORE(ptr, ir_LOAD_U16(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13402
13442
} else {
13403
13443
ZEND_UNREACHABLE();
13404
13444
}
13405
13445
break;
13406
13446
case ZEND_FFI_TYPE_SINT16:
13407
13447
if (val_info == MAY_BE_LONG) {
13408
13448
ir_STORE(ptr, ir_TRUNC_I16(jit_Z_LVAL(jit, val_addr)));
13449
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13450
+ ir_STORE(ptr, ir_LOAD_I16(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13409
13451
} else {
13410
13452
ZEND_UNREACHABLE();
13411
13453
}
@@ -13414,13 +13456,17 @@ static int zend_jit_ffi_write(zend_jit_ctx *jit,
13414
13456
case ZEND_FFI_TYPE_UINT32:
13415
13457
if (val_info == MAY_BE_LONG) {
13416
13458
ir_STORE(ptr, ir_TRUNC_U32(jit_Z_LVAL(jit, val_addr)));
13459
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13460
+ ir_STORE(ptr, ir_LOAD_U32(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13417
13461
} else {
13418
13462
ZEND_UNREACHABLE();
13419
13463
}
13420
13464
break;
13421
13465
case ZEND_FFI_TYPE_SINT32:
13422
13466
if (val_info == MAY_BE_LONG) {
13423
13467
ir_STORE(ptr, ir_TRUNC_I32(jit_Z_LVAL(jit, val_addr)));
13468
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13469
+ ir_STORE(ptr, ir_LOAD_I32(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13424
13470
} else {
13425
13471
ZEND_UNREACHABLE();
13426
13472
}
@@ -13429,6 +13475,8 @@ static int zend_jit_ffi_write(zend_jit_ctx *jit,
13429
13475
case ZEND_FFI_TYPE_SINT64:
13430
13476
if (val_info == MAY_BE_LONG) {
13431
13477
ir_STORE(ptr, jit_Z_LVAL(jit, val_addr));
13478
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13479
+ ir_STORE(ptr, ir_LOAD_I64(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13432
13480
} else {
13433
13481
ZEND_UNREACHABLE();
13434
13482
}
@@ -13438,6 +13486,8 @@ static int zend_jit_ffi_write(zend_jit_ctx *jit,
13438
13486
case ZEND_FFI_TYPE_SINT32:
13439
13487
if (val_info == MAY_BE_LONG) {
13440
13488
ir_STORE(ptr, jit_Z_LVAL(jit, val_addr));
13489
+ } else if (val_ffi_type && val_ffi_type->kind == ffi_type->kind) {
13490
+ ir_STORE(ptr, ir_LOAD_I32(jit_FFI_CDATA_PTR(jit, jit_Z_PTR(jit, val_addr))));
13441
13491
} else {
13442
13492
ZEND_UNREACHABLE();
13443
13493
}
@@ -13464,6 +13514,7 @@ static int zend_jit_ffi_assign_dim(zend_jit_ctx *jit,
13464
13514
zend_jit_addr val_def_addr,
13465
13515
zend_jit_addr res_addr,
13466
13516
zend_ffi_type *op1_ffi_type,
13517
+ zend_ffi_type *val_ffi_type,
13467
13518
zend_jit_ffi_info *ffi_info)
13468
13519
{
13469
13520
zend_ffi_type *el_type = ZEND_FFI_TYPE(op1_ffi_type->array.type);
@@ -13485,7 +13536,7 @@ static int zend_jit_ffi_assign_dim(zend_jit_ctx *jit,
13485
13536
13486
13537
ir_ref ptr = ir_ADD_A(cdata_ref, ir_MUL_L(jit_Z_LVAL(jit, op2_addr), ir_CONST_LONG(el_type->size)));
13487
13538
13488
- if (!zend_jit_ffi_write(jit, el_type, ptr, val_info, val_addr)) {
13539
+ if (!zend_jit_ffi_write(jit, el_type, ptr, val_info, val_addr, val_ffi_type )) {
13489
13540
return 0;
13490
13541
}
13491
13542
@@ -13779,6 +13830,16 @@ static int zend_jit_ffi_assign_op_helper(zend_jit_ctx *jit,
13779
13830
return 0;
13780
13831
}
13781
13832
break;
13833
+ case ZEND_FFI_TYPE_BOOL:
13834
+ type = IR_U8;
13835
+ ZEND_ASSERT(opcode == ZEND_BW_AND || opcode == ZEND_BW_OR);
13836
+ if (op2_info == MAY_BE_LONG) {
13837
+ op2 = ir_TRUNC_U8(jit_Z_LVAL(jit, op2_addr));
13838
+ } else {
13839
+ ZEND_UNREACHABLE();
13840
+ return 0;
13841
+ }
13842
+ break;
13782
13843
case ZEND_FFI_TYPE_UINT8:
13783
13844
type = IR_U8;
13784
13845
if (op2_info == MAY_BE_LONG) {
@@ -13789,6 +13850,7 @@ static int zend_jit_ffi_assign_op_helper(zend_jit_ctx *jit,
13789
13850
}
13790
13851
break;
13791
13852
case ZEND_FFI_TYPE_SINT8:
13853
+ case ZEND_FFI_TYPE_CHAR:
13792
13854
type = IR_I8;
13793
13855
if (op2_info == MAY_BE_LONG) {
13794
13856
op2 = ir_TRUNC_I8(jit_Z_LVAL(jit, op2_addr));
@@ -14917,6 +14979,7 @@ static int zend_jit_ffi_assign_obj(zend_jit_ctx *jit,
14917
14979
zend_jit_addr val_def_addr,
14918
14980
zend_jit_addr res_addr,
14919
14981
zend_ffi_type *op1_ffi_type,
14982
+ zend_ffi_type *val_ffi_type,
14920
14983
zend_jit_ffi_info *ffi_info)
14921
14984
{
14922
14985
zend_ffi_type *field_type = ZEND_FFI_TYPE(field->type);
@@ -14929,7 +14992,7 @@ static int zend_jit_ffi_assign_obj(zend_jit_ctx *jit,
14929
14992
ir_ref cdata_ref = ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
14930
14993
ir_ref ptr = ir_ADD_A(cdata_ref, ir_CONST_LONG(field->offset));
14931
14994
14932
- if (!zend_jit_ffi_write(jit, field_type, ptr, val_info, val_addr)) {
14995
+ if (!zend_jit_ffi_write(jit, field_type, ptr, val_info, val_addr, val_ffi_type )) {
14933
14996
return 0;
14934
14997
}
14935
14998
@@ -17612,13 +17675,10 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa
17612
17675
zend_ffi_type *op1_ffi_type = (zend_ffi_type*)(trace+2)->ptr;
17613
17676
if (op1_ffi_type
17614
17677
&& (op1_ffi_type->kind == ZEND_FFI_TYPE_ARRAY || op1_ffi_type->kind == ZEND_FFI_TYPE_POINTER)
17615
- && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind >= ZEND_FFI_TYPE_FLOAT
17616
- && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind <= ZEND_FFI_TYPE_ENUM
17617
- #if defined(IR_TARGET_X86)
17618
- && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind != ZEND_FFI_TYPE_UINT64
17619
- && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind != ZEND_FFI_TYPE_SINT64
17620
- #endif
17621
- && op2_info == MAY_BE_LONG) {
17678
+ && op2_info == MAY_BE_LONG
17679
+ && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind < ZEND_FFI_TYPE_POINTER
17680
+ && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind != ZEND_FFI_TYPE_VOID
17681
+ && zend_jit_ffi_supported_type(ZEND_FFI_TYPE(op1_ffi_type->array.type))) {
17622
17682
return 1;
17623
17683
}
17624
17684
}
@@ -17674,20 +17734,19 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa
17674
17734
&& (trace+1)->op == ZEND_JIT_TRACE_OP1_TYPE
17675
17735
&& (trace+2)->op == ZEND_JIT_TRACE_OP1_FFI_TYPE) {
17676
17736
zend_ffi_type *op1_ffi_type = (zend_ffi_type*)(trace+2)->ptr;
17737
+ zend_ffi_type *op3_ffi_type = NULL;
17738
+ uint32_t op1_data_info = OP1_DATA_INFO();
17739
+
17740
+ if ((trace+3)->op == ZEND_JIT_TRACE_OP3_TYPE
17741
+ && (trace+4)->op == ZEND_JIT_TRACE_OP3_FFI_TYPE) {
17742
+ op3_ffi_type = (zend_ffi_type*)(trace+4)->ptr;
17743
+ }
17744
+
17677
17745
if (op1_ffi_type
17678
17746
&& (op1_ffi_type->kind == ZEND_FFI_TYPE_ARRAY || op1_ffi_type->kind == ZEND_FFI_TYPE_POINTER)
17679
- && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind >= ZEND_FFI_TYPE_FLOAT
17680
- && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind <= ZEND_FFI_TYPE_ENUM
17681
- #if defined(IR_TARGET_X86)
17682
- && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind != ZEND_FFI_TYPE_UINT64
17683
- && ZEND_FFI_TYPE(op1_ffi_type->array.type)->kind != ZEND_FFI_TYPE_SINT64
17684
- #endif
17685
- && op2_info == MAY_BE_LONG) {
17686
- uint32_t op1_data_info = OP1_DATA_INFO();
17687
-
17688
- if (op1_data_info == MAY_BE_LONG || op1_data_info == MAY_BE_DOUBLE) {
17689
- return 1;
17690
- }
17747
+ && op2_info == MAY_BE_LONG
17748
+ && zend_jit_ffi_compatible(op1_ffi_type->array.type, op1_data_info, op3_ffi_type)) {
17749
+ return 1;
17691
17750
}
17692
17751
}
17693
17752
#endif
0 commit comments