@@ -6942,10 +6942,72 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
69426942 }
69436943 }
69446944#ifdef HAVE_FFI
6945- if (op1_ffi_symbols ) {
6945+ if (zend_ffi_api && op1_ce == zend_ffi_api -> scope_ce && ! ZEND_OBSERVER_ENABLED ) {
69466946 zend_string * name = Z_STR_P (RT_CONSTANT (opline , opline -> op2 ));
69476947
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" )) {
69497011 if (opline -> extended_value == 1
69507012 && (p + 1 )-> op == ZEND_JIT_TRACE_INIT_CALL
69517013 && (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
69577019 if (Z_TYPE_P (zv ) == IS_STRING ) {
69587020 zend_ffi_dcl * dcl = zend_ffi_api -> cache_type_get (Z_STR_P (zv ), op1_ffi_symbols );
69597021
6960- if (dcl ) {
7022+ if (dcl
7023+ && !ZEND_FFI_TYPE_IS_OWNED (dcl -> type )
7024+ && (dcl -> type -> attr & ZEND_FFI_ATTR_PERSISTENT )) {
69617025 if (!ffi_info ) {
69627026 ffi_info = zend_arena_calloc (& CG (arena ), ssa -> vars_count , sizeof (zend_jit_ffi_info ));
69637027 }
@@ -6967,12 +7031,16 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
69677031 }
69687032 frame_flags = TRACE_FRAME_MASK_FFI | TRACE_FRAME_FFI_FUNC_TYPE ;
69697033 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+ }
69717039 goto done ;
69727040 }
69737041 }
69747042 }
6975- } else {
7043+ } else if ( op1_ffi_symbols ) {
69767044 zend_ffi_symbol * sym = zend_hash_find_ptr (op1_ffi_symbols , name );
69777045
69787046 if (sym
@@ -7019,7 +7087,8 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
70197087 }
70207088#ifdef HAVE_FFI
70217089 if (opline -> op1_type == IS_CONST
7022- && opline -> op2_type == IS_CONST ) {
7090+ && opline -> op2_type == IS_CONST
7091+ && !ZEND_OBSERVER_ENABLED ) {
70237092 zval * zv = RT_CONSTANT (opline , opline -> op1 );
70247093 if (Z_TYPE_P (zv ) == IS_STRING
70257094 && (zend_string_equals_literal_ci (Z_STR_P (zv ), "FFI" )
0 commit comments