@@ -6942,10 +6942,72 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
6942
6942
}
6943
6943
}
6944
6944
#ifdef HAVE_FFI
6945
- if (op1_ffi_symbols ) {
6945
+ if (zend_ffi_api && op1_ce == zend_ffi_api -> scope_ce && ! ZEND_OBSERVER_ENABLED ) {
6946
6946
zend_string * name = Z_STR_P (RT_CONSTANT (opline , opline -> op2 ));
6947
6947
6948
- if (zend_string_equals_literal_ci (name , "type" )) {
6948
+ if (zend_string_equals_literal_ci (name , "new" )) {
6949
+ if (opline -> extended_value == 1
6950
+ // TODO: support for FFI::new() with 2 and 3 arguments ???
6951
+ && (p + 1 )-> op == ZEND_JIT_TRACE_INIT_CALL
6952
+ && (p + 2 )-> op == ZEND_JIT_TRACE_VM ) {
6953
+ if (((p + 2 )-> opline -> opcode == ZEND_SEND_VAL
6954
+ || (p + 2 )-> opline -> opcode == ZEND_SEND_VAL_EX )
6955
+ && (p + 2 )-> opline -> op1_type == IS_CONST ) {
6956
+ zval * zv = RT_CONSTANT ((p + 2 )-> opline , (p + 2 )-> opline -> op1 );
6957
+
6958
+ if (Z_TYPE_P (zv ) == IS_STRING ) {
6959
+ zend_ffi_dcl * dcl = zend_ffi_api -> cache_type_get (Z_STR_P (zv ), op1_ffi_symbols );
6960
+
6961
+ if (dcl
6962
+ && !ZEND_FFI_TYPE_IS_OWNED (dcl -> type )
6963
+ && (dcl -> type -> attr & ZEND_FFI_ATTR_PERSISTENT )
6964
+ && dcl -> type -> size != 0 ) {
6965
+ if (!ffi_info ) {
6966
+ ffi_info = zend_arena_calloc (& CG (arena ), ssa -> vars_count , sizeof (zend_jit_ffi_info ));
6967
+ }
6968
+ if (!zend_jit_ffi_symbols_guard (& ctx , opline , ssa ,
6969
+ ssa_op -> op1_use , -1 , op1_info , op1_addr , op1_ffi_symbols , ffi_info )) {
6970
+ goto jit_failure ;
6971
+ }
6972
+ frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_NEW ;
6973
+ frame_ffi_func_type = dcl -> type ;
6974
+ if (opline -> op1_type & (IS_VAR |IS_TMP_VAR )) {
6975
+ frame_ffi_func_ref = jit_Z_PTR (jit , op1_addr );
6976
+ } else {
6977
+ frame_ffi_func_ref = IR_UNUSED ;
6978
+ }
6979
+ goto done ;
6980
+ }
6981
+ }
6982
+ } else if ((p + 2 )-> opline -> opcode == ZEND_SEND_VAR_EX
6983
+ && (p + 3 )-> op == ZEND_JIT_TRACE_OP1_TYPE
6984
+ && (p + 3 )-> ce == zend_ffi_api -> ctype_ce
6985
+ && (p + 4 )-> op == ZEND_JIT_TRACE_OP1_FFI_TYPE ) {
6986
+ zend_ffi_type * type = (zend_ffi_type * )(p + 4 )-> ptr ;
6987
+
6988
+ if (!ZEND_FFI_TYPE_IS_OWNED (type )
6989
+ && (type -> attr & ZEND_FFI_ATTR_PERSISTENT )
6990
+ && type -> size != 0 ) {
6991
+ if (!ffi_info ) {
6992
+ ffi_info = zend_arena_calloc (& CG (arena ), ssa -> vars_count , sizeof (zend_jit_ffi_info ));
6993
+ }
6994
+ if (!zend_jit_ffi_symbols_guard (& ctx , opline , ssa ,
6995
+ ssa_op -> op1_use , -1 , op1_info , op1_addr , op1_ffi_symbols , ffi_info )) {
6996
+ goto jit_failure ;
6997
+ }
6998
+ // TODO: Guard for FFI::CType argument
6999
+ frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_NEW ;
7000
+ frame_ffi_func_type = type ;
7001
+ if (opline -> op1_type & (IS_VAR |IS_TMP_VAR )) {
7002
+ frame_ffi_func_ref = jit_Z_PTR (jit , op1_addr );
7003
+ } else {
7004
+ frame_ffi_func_ref = IR_UNUSED ;
7005
+ }
7006
+ goto done ;
7007
+ }
7008
+ }
7009
+ }
7010
+ } else if (zend_string_equals_literal_ci (name , "type" )) {
6949
7011
if (opline -> extended_value == 1
6950
7012
&& (p + 1 )-> op == ZEND_JIT_TRACE_INIT_CALL
6951
7013
&& (p + 2 )-> op == ZEND_JIT_TRACE_VM
@@ -6957,7 +7019,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
6957
7019
if (Z_TYPE_P (zv ) == IS_STRING ) {
6958
7020
zend_ffi_dcl * dcl = zend_ffi_api -> cache_type_get (Z_STR_P (zv ), op1_ffi_symbols );
6959
7021
6960
- if (dcl ) {
7022
+ if (dcl
7023
+ && !ZEND_FFI_TYPE_IS_OWNED (dcl -> type )
7024
+ && (dcl -> type -> attr & ZEND_FFI_ATTR_PERSISTENT )) {
6961
7025
if (!ffi_info ) {
6962
7026
ffi_info = zend_arena_calloc (& CG (arena ), ssa -> vars_count , sizeof (zend_jit_ffi_info ));
6963
7027
}
@@ -6967,12 +7031,16 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
6967
7031
}
6968
7032
frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_TYPE ;
6969
7033
frame_ffi_func_type = dcl -> type ;
6970
- frame_ffi_func_ref = IR_UNUSED ;
7034
+ if (opline -> op1_type & (IS_VAR |IS_TMP_VAR )) {
7035
+ frame_ffi_func_ref = jit_Z_PTR (jit , op1_addr );
7036
+ } else {
7037
+ frame_ffi_func_ref = IR_UNUSED ;
7038
+ }
6971
7039
goto done ;
6972
7040
}
6973
7041
}
6974
7042
}
6975
- } else {
7043
+ } else if ( op1_ffi_symbols ) {
6976
7044
zend_ffi_symbol * sym = zend_hash_find_ptr (op1_ffi_symbols , name );
6977
7045
6978
7046
if (sym
@@ -7019,7 +7087,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
7019
7087
}
7020
7088
#ifdef HAVE_FFI
7021
7089
if (opline -> op1_type == IS_CONST
7022
- && opline -> op2_type == IS_CONST ) {
7090
+ && opline -> op2_type == IS_CONST
7091
+ && !ZEND_OBSERVER_ENABLED ) {
7023
7092
zval * zv = RT_CONSTANT (opline , opline -> op1 );
7024
7093
if (Z_TYPE_P (zv ) == IS_STRING
7025
7094
&& (zend_string_equals_literal_ci (Z_STR_P (zv ), "FFI" )
0 commit comments