@@ -819,8 +819,27 @@ static int zend_jit_ffi_write(zend_jit_ctx *jit,
819819 }
820820 }
821821 break ;
822- case ZEND_FFI_TYPE_SINT8 :
823822 case ZEND_FFI_TYPE_CHAR :
823+ if ((val_info & (MAY_BE_GUARD |MAY_BE_REF |MAY_BE_ANY |MAY_BE_UNDEF )) == MAY_BE_STRING ) {
824+ ir_ref str = jit_Z_PTR (jit , val_addr );
825+
826+ // TODO: ZSTR_LEN() == 1 ???
827+ ref = ir_LOAD_C (ir_ADD_OFFSET (str , offsetof(zend_string , val )));
828+ ir_STORE (ptr , ref );
829+ if (res_addr ) {
830+ ir_ref type_info = jit_Z_TYPE_INFO (jit , val_addr );
831+ ir_ref if_refcounted = ir_IF (ir_AND_U32 (type_info , ir_CONST_U32 (0xff00 )));
832+
833+ ir_IF_TRUE (if_refcounted );
834+ jit_GC_ADDREF (jit , str );
835+ ir_MERGE_WITH_EMPTY_FALSE (if_refcounted );
836+ jit_set_Z_PTR (jit , res_addr , str );
837+ jit_set_Z_TYPE_INFO_ex (jit , res_addr , type_info );
838+ }
839+ return 1 ;
840+ }
841+ ZEND_FALLTHROUGH ;
842+ case ZEND_FFI_TYPE_SINT8 :
824843 if (val_info == MAY_BE_LONG ) {
825844 ref = ir_TRUNC_I8 (jit_Z_LVAL (jit , val_addr ));
826845 } else if (val_ffi_type && val_ffi_type -> kind == ffi_type -> kind ) {
@@ -1311,6 +1330,53 @@ static int zend_jit_ffi_fetch_obj(zend_jit_ctx *jit,
13111330 return 1 ;
13121331}
13131332
1333+ static int zend_jit_ffi_fetch_val (zend_jit_ctx * jit ,
1334+ const zend_op * opline ,
1335+ const zend_op_array * op_array ,
1336+ zend_ssa * ssa ,
1337+ const zend_ssa_op * ssa_op ,
1338+ uint32_t op1_info ,
1339+ zend_jit_addr op1_addr ,
1340+ bool op1_indirect ,
1341+ bool op1_avoid_refcounting ,
1342+ zend_jit_addr res_addr ,
1343+ zend_ffi_type * op1_ffi_type ,
1344+ zend_jit_ffi_info * ffi_info )
1345+ {
1346+ uint32_t res_info = RES_INFO ();
1347+ ir_ref obj_ref = jit_Z_PTR (jit , op1_addr );
1348+
1349+ if (!zend_jit_ffi_guard (jit , opline , ssa , ssa_op -> op1_use , -1 , obj_ref , op1_ffi_type , ffi_info )) {
1350+ return 0 ;
1351+ }
1352+
1353+ ir_ref ptr = ir_LOAD_A (ir_ADD_OFFSET (obj_ref , offsetof(zend_ffi_cdata , ptr )));
1354+
1355+ if (opline -> opcode == ZEND_FETCH_OBJ_W ) {
1356+ jit_set_Z_PTR (jit , res_addr ,
1357+ ir_CALL_2 (IR_ADDR , ir_CONST_FUNC (zend_ffi_cdata_create ),
1358+ ptr , ir_CONST_ADDR (op1_ffi_type )));
1359+ jit_set_Z_TYPE_INFO (jit , res_addr , IS_OBJECT_EX );
1360+ } else {
1361+ if (!zend_jit_ffi_read (jit , op1_ffi_type , ptr , res_addr )) {
1362+ return 0 ;
1363+ }
1364+ }
1365+
1366+ if (res_info & MAY_BE_GUARD ) {
1367+ // TODO: ???
1368+ ssa -> var_info [ssa_op -> result_def ].type &= ~MAY_BE_GUARD ;
1369+ }
1370+
1371+ if (!op1_avoid_refcounting && !op1_indirect ) {
1372+ if (opline -> op1_type & (IS_TMP_VAR |IS_VAR )) {
1373+ jit_FREE_OP (jit , opline -> op1_type , opline -> op1 , op1_info , opline );
1374+ }
1375+ }
1376+
1377+ return 1 ;
1378+ }
1379+
13141380static int zend_jit_ffi_fetch_sym (zend_jit_ctx * jit ,
13151381 const zend_op * opline ,
13161382 const zend_op_array * op_array ,
@@ -1410,6 +1476,54 @@ static int zend_jit_ffi_assign_obj(zend_jit_ctx *jit,
14101476 return 1 ;
14111477}
14121478
1479+ static int zend_jit_ffi_assign_val (zend_jit_ctx * jit ,
1480+ const zend_op * opline ,
1481+ const zend_op_array * op_array ,
1482+ zend_ssa * ssa ,
1483+ const zend_ssa_op * ssa_op ,
1484+ uint32_t op1_info ,
1485+ zend_jit_addr op1_addr ,
1486+ bool op1_indirect ,
1487+ uint32_t val_info ,
1488+ zend_jit_addr val_addr ,
1489+ zend_jit_addr val_def_addr ,
1490+ zend_jit_addr res_addr ,
1491+ zend_ffi_type * op1_ffi_type ,
1492+ zend_ffi_type * val_ffi_type ,
1493+ zend_jit_ffi_info * ffi_info )
1494+ {
1495+ ir_ref obj_ref = jit_Z_PTR (jit , op1_addr );
1496+
1497+ if (!zend_jit_ffi_guard (jit , opline , ssa , ssa_op -> op1_use , ssa_op -> op1_def , obj_ref , op1_ffi_type , ffi_info )) {
1498+ return 0 ;
1499+ }
1500+
1501+ if (val_addr != val_def_addr && val_def_addr ) {
1502+ if (!zend_jit_update_regs (jit , (opline + 1 )-> op1 .var , val_addr , val_def_addr , val_info )) {
1503+ return 0 ;
1504+ }
1505+ if (Z_MODE (val_def_addr ) == IS_REG && Z_MODE (val_addr ) != IS_REG ) {
1506+ val_addr = val_def_addr ;
1507+ }
1508+ }
1509+
1510+ ir_ref ptr = ir_LOAD_A (ir_ADD_OFFSET (obj_ref , offsetof(zend_ffi_cdata , ptr )));
1511+
1512+ ZEND_ASSERT (!res_addr || RETURN_VALUE_USED (opline ));
1513+
1514+ if (!zend_jit_ffi_write (jit , op1_ffi_type , ptr , val_info , val_addr , val_ffi_type , res_addr )) {
1515+ return 0 ;
1516+ }
1517+
1518+ jit_FREE_OP (jit , (opline + 1 )-> op1_type , (opline + 1 )-> op1 , val_info , opline );
1519+
1520+ if (!op1_indirect ) {
1521+ jit_FREE_OP (jit , opline -> op1_type , opline -> op1 , op1_info , opline );
1522+ }
1523+
1524+ return 1 ;
1525+ }
1526+
14131527static int zend_jit_ffi_assign_sym (zend_jit_ctx * jit ,
14141528 const zend_op * opline ,
14151529 const zend_op_array * op_array ,
@@ -1496,6 +1610,41 @@ static int zend_jit_ffi_assign_obj_op(zend_jit_ctx *jit,
14961610 return 1 ;
14971611}
14981612
1613+ static int zend_jit_ffi_assign_val_op (zend_jit_ctx * jit ,
1614+ const zend_op * opline ,
1615+ const zend_op_array * op_array ,
1616+ zend_ssa * ssa ,
1617+ const zend_ssa_op * ssa_op ,
1618+ uint32_t op1_info ,
1619+ zend_jit_addr op1_addr ,
1620+ bool op1_indirect ,
1621+ uint32_t val_info ,
1622+ zend_jit_addr val_addr ,
1623+ zend_ffi_type * op1_ffi_type ,
1624+ zend_jit_ffi_info * ffi_info )
1625+ {
1626+ ir_ref obj_ref = jit_Z_PTR (jit , op1_addr );
1627+
1628+ if (!zend_jit_ffi_guard (jit , opline , ssa , ssa_op -> op1_use , ssa_op -> op1_def , obj_ref , op1_ffi_type , ffi_info )) {
1629+ return 0 ;
1630+ }
1631+
1632+ ir_ref ptr = ir_LOAD_A (ir_ADD_OFFSET (obj_ref , offsetof(zend_ffi_cdata , ptr )));
1633+
1634+ if (!zend_jit_ffi_assign_op_helper (jit , opline , opline -> extended_value ,
1635+ op1_ffi_type , ptr , val_info , val_addr )) {
1636+ return 0 ;
1637+ }
1638+
1639+ jit_FREE_OP (jit , (opline + 1 )-> op1_type , (opline + 1 )-> op1 , val_info , opline );
1640+
1641+ if (!op1_indirect ) {
1642+ jit_FREE_OP (jit , opline -> op1_type , opline -> op1 , op1_info , opline );
1643+ }
1644+
1645+ return 1 ;
1646+ }
1647+
14991648static int zend_jit_ffi_assign_sym_op (zend_jit_ctx * jit ,
15001649 const zend_op * opline ,
15011650 const zend_op_array * op_array ,
@@ -1767,6 +1916,37 @@ static int zend_jit_ffi_incdec_obj(zend_jit_ctx *jit,
17671916 return 1 ;
17681917}
17691918
1919+ static int zend_jit_ffi_incdec_val (zend_jit_ctx * jit ,
1920+ const zend_op * opline ,
1921+ const zend_op_array * op_array ,
1922+ zend_ssa * ssa ,
1923+ const zend_ssa_op * ssa_op ,
1924+ uint32_t op1_info ,
1925+ zend_jit_addr op1_addr ,
1926+ bool op1_indirect ,
1927+ zend_jit_addr res_addr ,
1928+ zend_ffi_type * op1_ffi_type ,
1929+ zend_jit_ffi_info * ffi_info )
1930+ {
1931+ ir_ref obj_ref = jit_Z_PTR (jit , op1_addr );
1932+
1933+ if (!zend_jit_ffi_guard (jit , opline , ssa , ssa_op -> op1_use , ssa_op -> op1_def , obj_ref , op1_ffi_type , ffi_info )) {
1934+ return 0 ;
1935+ }
1936+
1937+ ir_ref ptr = ir_LOAD_A (ir_ADD_OFFSET (obj_ref , offsetof(zend_ffi_cdata , ptr )));
1938+
1939+ if (!zend_jit_ffi_incdec_helper (jit , opline , opline -> opcode , op1_ffi_type , ptr , res_addr )) {
1940+ return 0 ;
1941+ }
1942+
1943+ if (!op1_indirect ) {
1944+ jit_FREE_OP (jit , opline -> op1_type , opline -> op1 , op1_info , opline );
1945+ }
1946+
1947+ return 1 ;
1948+ }
1949+
17701950static int zend_jit_ffi_incdec_sym (zend_jit_ctx * jit ,
17711951 const zend_op * opline ,
17721952 const zend_op_array * op_array ,
0 commit comments