@@ -12595,6 +12595,16 @@ static int zend_jit_ffi_read(zend_jit_ctx *jit,
1259512595 res_type = IS_LONG;
1259612596 break;
1259712597#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;
1259812608 default:
1259912609 ZEND_UNREACHABLE();
1260012610 }
@@ -12649,6 +12659,11 @@ static int zend_jit_ffi_guard(zend_jit_ctx *jit,
1264912659 return 1;
1265012660}
1265112661
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+
1265212667static int zend_jit_ffi_fetch_dim_read(zend_jit_ctx *jit,
1265312668 const zend_op *opline,
1265412669 zend_ssa *ssa,
@@ -12675,7 +12690,8 @@ static int zend_jit_ffi_fetch_dim_read(zend_jit_ctx *jit,
1267512690 return 0;
1267612691 }
1267712692
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)));
1267912695
1268012696 if (op1_ffi_type->kind == ZEND_FFI_TYPE_POINTER) {
1268112697 cdata_ref = ir_LOAD_A(cdata_ref);
@@ -13361,14 +13377,17 @@ static int zend_jit_ffi_write(zend_jit_ctx *jit,
1336113377 zend_ffi_type *ffi_type,
1336213378 ir_ref ptr,
1336313379 uint32_t val_info,
13364- zend_jit_addr val_addr)
13380+ zend_jit_addr val_addr,
13381+ zend_ffi_type *val_ffi_type)
1336513382{
1336613383 switch (ffi_type->kind) {
1336713384 case ZEND_FFI_TYPE_FLOAT:
1336813385 if (val_info == MAY_BE_LONG) {
1336913386 ir_STORE(ptr, ir_INT2F(jit_Z_LVAL(jit, val_addr)));
1337013387 } else if (val_info == MAY_BE_DOUBLE) {
1337113388 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))));
1337213391 } else {
1337313392 ZEND_UNREACHABLE();
1337413393 }
@@ -13378,34 +13397,57 @@ static int zend_jit_ffi_write(zend_jit_ctx *jit,
1337813397 ir_STORE(ptr, ir_INT2D(jit_Z_LVAL(jit, val_addr)));
1337913398 } else if (val_info == MAY_BE_DOUBLE) {
1338013399 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))));
1338113402 } else {
1338213403 ZEND_UNREACHABLE();
1338313404 }
1338413405 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;
1338513418 case ZEND_FFI_TYPE_UINT8:
1338613419 if (val_info == MAY_BE_LONG) {
1338713420 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))));
1338813423 } else {
1338913424 ZEND_UNREACHABLE();
1339013425 }
1339113426 break;
1339213427 case ZEND_FFI_TYPE_SINT8:
13428+ case ZEND_FFI_TYPE_CHAR:
1339313429 if (val_info == MAY_BE_LONG) {
1339413430 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))));
1339513433 } else {
1339613434 ZEND_UNREACHABLE();
1339713435 }
1339813436 break;
1339913437 case ZEND_FFI_TYPE_UINT16:
1340013438 if (val_info == MAY_BE_LONG) {
1340113439 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))));
1340213442 } else {
1340313443 ZEND_UNREACHABLE();
1340413444 }
1340513445 break;
1340613446 case ZEND_FFI_TYPE_SINT16:
1340713447 if (val_info == MAY_BE_LONG) {
1340813448 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))));
1340913451 } else {
1341013452 ZEND_UNREACHABLE();
1341113453 }
@@ -13414,13 +13456,17 @@ static int zend_jit_ffi_write(zend_jit_ctx *jit,
1341413456 case ZEND_FFI_TYPE_UINT32:
1341513457 if (val_info == MAY_BE_LONG) {
1341613458 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))));
1341713461 } else {
1341813462 ZEND_UNREACHABLE();
1341913463 }
1342013464 break;
1342113465 case ZEND_FFI_TYPE_SINT32:
1342213466 if (val_info == MAY_BE_LONG) {
1342313467 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))));
1342413470 } else {
1342513471 ZEND_UNREACHABLE();
1342613472 }
@@ -13429,6 +13475,8 @@ static int zend_jit_ffi_write(zend_jit_ctx *jit,
1342913475 case ZEND_FFI_TYPE_SINT64:
1343013476 if (val_info == MAY_BE_LONG) {
1343113477 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))));
1343213480 } else {
1343313481 ZEND_UNREACHABLE();
1343413482 }
@@ -13438,6 +13486,8 @@ static int zend_jit_ffi_write(zend_jit_ctx *jit,
1343813486 case ZEND_FFI_TYPE_SINT32:
1343913487 if (val_info == MAY_BE_LONG) {
1344013488 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))));
1344113491 } else {
1344213492 ZEND_UNREACHABLE();
1344313493 }
@@ -13464,6 +13514,7 @@ static int zend_jit_ffi_assign_dim(zend_jit_ctx *jit,
1346413514 zend_jit_addr val_def_addr,
1346513515 zend_jit_addr res_addr,
1346613516 zend_ffi_type *op1_ffi_type,
13517+ zend_ffi_type *val_ffi_type,
1346713518 zend_jit_ffi_info *ffi_info)
1346813519{
1346913520 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,
1348513536
1348613537 ir_ref ptr = ir_ADD_A(cdata_ref, ir_MUL_L(jit_Z_LVAL(jit, op2_addr), ir_CONST_LONG(el_type->size)));
1348713538
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 )) {
1348913540 return 0;
1349013541 }
1349113542
@@ -13779,6 +13830,16 @@ static int zend_jit_ffi_assign_op_helper(zend_jit_ctx *jit,
1377913830 return 0;
1378013831 }
1378113832 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;
1378213843 case ZEND_FFI_TYPE_UINT8:
1378313844 type = IR_U8;
1378413845 if (op2_info == MAY_BE_LONG) {
@@ -13789,6 +13850,7 @@ static int zend_jit_ffi_assign_op_helper(zend_jit_ctx *jit,
1378913850 }
1379013851 break;
1379113852 case ZEND_FFI_TYPE_SINT8:
13853+ case ZEND_FFI_TYPE_CHAR:
1379213854 type = IR_I8;
1379313855 if (op2_info == MAY_BE_LONG) {
1379413856 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,
1491714979 zend_jit_addr val_def_addr,
1491814980 zend_jit_addr res_addr,
1491914981 zend_ffi_type *op1_ffi_type,
14982+ zend_ffi_type *val_ffi_type,
1492014983 zend_jit_ffi_info *ffi_info)
1492114984{
1492214985 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,
1492914992 ir_ref cdata_ref = ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_ffi_cdata, ptr)));
1493014993 ir_ref ptr = ir_ADD_A(cdata_ref, ir_CONST_LONG(field->offset));
1493114994
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 )) {
1493314996 return 0;
1493414997 }
1493514998
@@ -17612,13 +17675,10 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa
1761217675 zend_ffi_type *op1_ffi_type = (zend_ffi_type*)(trace+2)->ptr;
1761317676 if (op1_ffi_type
1761417677 && (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))) {
1762217682 return 1;
1762317683 }
1762417684 }
@@ -17674,20 +17734,19 @@ static bool zend_jit_opline_supports_reg(const zend_op_array *op_array, zend_ssa
1767417734 && (trace+1)->op == ZEND_JIT_TRACE_OP1_TYPE
1767517735 && (trace+2)->op == ZEND_JIT_TRACE_OP1_FFI_TYPE) {
1767617736 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+
1767717745 if (op1_ffi_type
1767817746 && (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;
1769117750 }
1769217751 }
1769317752#endif
0 commit comments