@@ -178,6 +178,141 @@ static int zend_jit_ffi_send_val(zend_jit_ctx *jit,
178178 SET_STACK_TYPE (stack , 1 , IS_LONG , 0 );
179179 SET_STACK_REF_EX (stack , 1 , ref , 0 );
180180 }
181+ } else if (TRACE_FRAME_FFI_FUNC (call ) == TRACE_FRAME_FFI_FUNC_MEMCPY ) {
182+ if (opline -> op2 .num == 1 ) {
183+ ZEND_ASSERT (op1_ffi_type );
184+ if (op1_ffi_type -> kind == ZEND_FFI_TYPE_POINTER ) {
185+ arg_flags |= ZREG_FFI_PTR_LOAD ;
186+ }
187+ if (opline -> op1_type & (IS_VAR |IS_TMP_VAR )) {
188+ arg_flags |= ZREG_FFI_ZVAL_DTOR ;
189+ }
190+ if (op1_info & MAY_BE_REF ) {
191+ arg_flags |= ZREG_FFI_ZVAL_DEREF ;
192+ }
193+ ref = jit_Z_PTR (jit , op1_addr );
194+ SET_STACK_TYPE (stack , 0 , IS_OBJECT , 0 );
195+ SET_STACK_REF_EX (stack , 0 , ref , arg_flags );
196+ } else if (opline -> op2 .num == 2 ) {
197+ if (op1_ffi_type ) {
198+ if (op1_ffi_type -> kind == ZEND_FFI_TYPE_POINTER ) {
199+ arg_flags |= ZREG_FFI_PTR_LOAD ;
200+ }
201+ if (opline -> op1_type & (IS_VAR |IS_TMP_VAR )) {
202+ arg_flags |= ZREG_FFI_ZVAL_DTOR ;
203+ }
204+ if (op1_info & MAY_BE_REF ) {
205+ arg_flags |= ZREG_FFI_ZVAL_DEREF ;
206+ }
207+ ref = jit_Z_PTR (jit , op1_addr );
208+ SET_STACK_TYPE (stack , 1 , IS_OBJECT , 0 );
209+ SET_STACK_REF_EX (stack , 1 , ref , arg_flags );
210+ } else {
211+ ZEND_ASSERT ((op1_info & (MAY_BE_ANY |MAY_BE_UNDEF )) == MAY_BE_STRING );
212+ if (op1_info & MAY_BE_REF ) {
213+ arg_flags |= ZREG_FFI_ZVAL_DEREF ;
214+ }
215+ if (opline -> op1_type & (IS_VAR |IS_TMP_VAR )) {
216+ arg_flags |= ZREG_FFI_ZVAL_DTOR ;
217+ }
218+ ref = jit_Z_PTR (jit , op1_addr );
219+ SET_STACK_TYPE (stack , 1 , IS_STRING , 0 );
220+ SET_STACK_REF_EX (stack , 1 , ref , arg_flags );
221+ }
222+ } else {
223+ ZEND_ASSERT (opline -> op2 .num == 3 );
224+ ZEND_ASSERT (op1_info == MAY_BE_LONG );
225+ ref = jit_Z_LVAL (jit , op1_addr );
226+ SET_STACK_TYPE (stack , 2 , IS_LONG , 0 );
227+ SET_STACK_REF_EX (stack , 2 , ref , 0 );
228+ }
229+ } else if (TRACE_FRAME_FFI_FUNC (call ) == TRACE_FRAME_FFI_FUNC_MEMCMP ) {
230+ if (opline -> op2 .num == 1 ) {
231+ if (op1_ffi_type ) {
232+ if (op1_ffi_type -> kind == ZEND_FFI_TYPE_POINTER ) {
233+ arg_flags |= ZREG_FFI_PTR_LOAD ;
234+ }
235+ if (opline -> op1_type & (IS_VAR |IS_TMP_VAR )) {
236+ arg_flags |= ZREG_FFI_ZVAL_DTOR ;
237+ }
238+ if (op1_info & MAY_BE_REF ) {
239+ arg_flags |= ZREG_FFI_ZVAL_DEREF ;
240+ }
241+ ref = jit_Z_PTR (jit , op1_addr );
242+ SET_STACK_TYPE (stack , 0 , IS_OBJECT , 0 );
243+ SET_STACK_REF_EX (stack , 0 , ref , arg_flags );
244+ } else {
245+ ZEND_ASSERT ((op1_info & (MAY_BE_ANY |MAY_BE_UNDEF )) == MAY_BE_STRING );
246+ if (op1_info & MAY_BE_REF ) {
247+ arg_flags |= ZREG_FFI_ZVAL_DEREF ;
248+ }
249+ if (opline -> op1_type & (IS_VAR |IS_TMP_VAR )) {
250+ arg_flags |= ZREG_FFI_ZVAL_DTOR ;
251+ }
252+ ref = jit_Z_PTR (jit , op1_addr );
253+ SET_STACK_TYPE (stack , 0 , IS_STRING , 0 );
254+ SET_STACK_REF_EX (stack , 0 , ref , arg_flags );
255+ }
256+ } else if (opline -> op2 .num == 2 ) {
257+ if (op1_ffi_type ) {
258+ if (op1_ffi_type -> kind == ZEND_FFI_TYPE_POINTER ) {
259+ arg_flags |= ZREG_FFI_PTR_LOAD ;
260+ }
261+ if (opline -> op1_type & (IS_VAR |IS_TMP_VAR )) {
262+ arg_flags |= ZREG_FFI_ZVAL_DTOR ;
263+ }
264+ if (op1_info & MAY_BE_REF ) {
265+ arg_flags |= ZREG_FFI_ZVAL_DEREF ;
266+ }
267+ ref = jit_Z_PTR (jit , op1_addr );
268+ SET_STACK_TYPE (stack , 1 , IS_OBJECT , 0 );
269+ SET_STACK_REF_EX (stack , 1 , ref , arg_flags );
270+ } else {
271+ ZEND_ASSERT ((op1_info & (MAY_BE_ANY |MAY_BE_UNDEF )) == MAY_BE_STRING );
272+ if (op1_info & MAY_BE_REF ) {
273+ arg_flags |= ZREG_FFI_ZVAL_DEREF ;
274+ }
275+ if (opline -> op1_type & (IS_VAR |IS_TMP_VAR )) {
276+ arg_flags |= ZREG_FFI_ZVAL_DTOR ;
277+ }
278+ ref = jit_Z_PTR (jit , op1_addr );
279+ SET_STACK_TYPE (stack , 1 , IS_STRING , 0 );
280+ SET_STACK_REF_EX (stack , 1 , ref , arg_flags );
281+ }
282+ } else {
283+ ZEND_ASSERT (opline -> op2 .num == 3 );
284+ ZEND_ASSERT (op1_info == MAY_BE_LONG );
285+ ref = jit_Z_LVAL (jit , op1_addr );
286+ SET_STACK_TYPE (stack , 2 , IS_LONG , 0 );
287+ SET_STACK_REF_EX (stack , 2 , ref , 0 );
288+ }
289+ } else if (TRACE_FRAME_FFI_FUNC (call ) == TRACE_FRAME_FFI_FUNC_MEMSET ) {
290+ if (opline -> op2 .num == 1 ) {
291+ ZEND_ASSERT (op1_ffi_type );
292+ if (op1_ffi_type -> kind == ZEND_FFI_TYPE_POINTER ) {
293+ arg_flags |= ZREG_FFI_PTR_LOAD ;
294+ }
295+ if (opline -> op1_type & (IS_VAR |IS_TMP_VAR )) {
296+ arg_flags |= ZREG_FFI_ZVAL_DTOR ;
297+ }
298+ if (op1_info & MAY_BE_REF ) {
299+ arg_flags |= ZREG_FFI_ZVAL_DEREF ;
300+ }
301+ ref = jit_Z_PTR (jit , op1_addr );
302+ SET_STACK_TYPE (stack , 0 , IS_OBJECT , 0 );
303+ SET_STACK_REF_EX (stack , 0 , ref , arg_flags );
304+ } else if (opline -> op2 .num == 2 ) {
305+ ZEND_ASSERT (op1_info == MAY_BE_LONG );
306+ ref = jit_Z_LVAL (jit , op1_addr );
307+ SET_STACK_TYPE (stack , 1 , IS_LONG , 0 );
308+ SET_STACK_REF_EX (stack , 1 , ref , 0 );
309+ } else {
310+ ZEND_ASSERT (opline -> op2 .num == 3 );
311+ ZEND_ASSERT (op1_info == MAY_BE_LONG );
312+ ref = jit_Z_LVAL (jit , op1_addr );
313+ SET_STACK_TYPE (stack , 2 , IS_LONG , 0 );
314+ SET_STACK_REF_EX (stack , 2 , ref , 0 );
315+ }
181316 } else {
182317 ZEND_UNREACHABLE ();
183318 }
@@ -494,6 +629,108 @@ static int zend_jit_ffi_do_call(zend_jit_ctx *jit,
494629 ir_CALL_3 (IR_VOID , ir_CONST_FC_FUNC (zend_jit_zval_stringl ),
495630 jit_ZVAL_ADDR (jit , res_addr ), ref , STACK_REF (stack , 1 ));
496631 }
632+ } else if (TRACE_FRAME_FFI_FUNC (call ) == TRACE_FRAME_FFI_FUNC_MEMCPY ) {
633+ ir_ref ref2 ;
634+
635+ ref = STACK_REF (stack , 0 );
636+ if (STACK_FLAGS (stack , 0 ) & ZREG_FFI_ZVAL_DEREF ) {
637+ // TODO: try to remove this dereference ???
638+ ref = zend_jit_gc_deref (jit , ref );
639+ }
640+ ref = jit_FFI_CDATA_PTR (jit , ref );
641+ if (STACK_FLAGS (stack , 0 ) & ZREG_FFI_PTR_LOAD ) {
642+ ref = ir_LOAD_A (ref );
643+ }
644+
645+ if (STACK_TYPE (stack , 1 ) == IS_OBJECT ) {
646+ ref2 = STACK_REF (stack , 1 );
647+ if (STACK_FLAGS (stack , 1 ) & ZREG_FFI_ZVAL_DEREF ) {
648+ // TODO: try to remove this dereference ???
649+ ref2 = zend_jit_gc_deref (jit , ref2 );
650+ }
651+ ref2 = jit_FFI_CDATA_PTR (jit , ref2 );
652+ if (STACK_FLAGS (stack , 1 ) & ZREG_FFI_PTR_LOAD ) {
653+ ref2 = ir_LOAD_A (ref2 );
654+ }
655+ } else {
656+ ZEND_ASSERT (STACK_TYPE (stack , 1 ) == IS_STRING );
657+ ref2 = STACK_REF (stack , 1 );
658+ if (STACK_FLAGS (stack , 1 ) & ZREG_FFI_ZVAL_DEREF ) {
659+ // TODO: try to remove this dereference ???
660+ ref2 = zend_jit_gc_deref (jit , ref2 );
661+ }
662+ ref2 = ir_ADD_OFFSET (ref2 , offsetof(zend_string , val ));
663+ }
664+
665+ ir_CALL_3 (IR_VOID , ir_CONST_FUNC (memcpy ), ref , ref2 , STACK_REF (stack , 2 ));
666+ if (res_addr ) {
667+ jit_set_Z_TYPE_INFO (jit , res_addr , IS_NULL );
668+ }
669+ } else if (TRACE_FRAME_FFI_FUNC (call ) == TRACE_FRAME_FFI_FUNC_MEMCMP ) {
670+ ir_ref ref2 ;
671+
672+ if (STACK_TYPE (stack , 0 ) == IS_OBJECT ) {
673+ ref = STACK_REF (stack , 0 );
674+ if (STACK_FLAGS (stack , 0 ) & ZREG_FFI_ZVAL_DEREF ) {
675+ // TODO: try to remove this dereference ???
676+ ref = zend_jit_gc_deref (jit , ref );
677+ }
678+ ref = jit_FFI_CDATA_PTR (jit , ref );
679+ if (STACK_FLAGS (stack , 0 ) & ZREG_FFI_PTR_LOAD ) {
680+ ref = ir_LOAD_A (ref );
681+ }
682+ } else {
683+ ZEND_ASSERT (STACK_TYPE (stack , 0 ) == IS_STRING );
684+ ref = STACK_REF (stack , 0 );
685+ if (STACK_FLAGS (stack , 0 ) & ZREG_FFI_ZVAL_DEREF ) {
686+ // TODO: try to remove this dereference ???
687+ ref = zend_jit_gc_deref (jit , ref );
688+ }
689+ ref = ir_ADD_OFFSET (ref , offsetof(zend_string , val ));
690+ }
691+
692+ if (STACK_TYPE (stack , 1 ) == IS_OBJECT ) {
693+ ref2 = STACK_REF (stack , 1 );
694+ if (STACK_FLAGS (stack , 1 ) & ZREG_FFI_ZVAL_DEREF ) {
695+ // TODO: try to remove this dereference ???
696+ ref2 = zend_jit_gc_deref (jit , ref2 );
697+ }
698+ ref2 = jit_FFI_CDATA_PTR (jit , ref2 );
699+ if (STACK_FLAGS (stack , 1 ) & ZREG_FFI_PTR_LOAD ) {
700+ ref2 = ir_LOAD_A (ref2 );
701+ }
702+ } else {
703+ ZEND_ASSERT (STACK_TYPE (stack , 1 ) == IS_STRING );
704+ ref2 = STACK_REF (stack , 1 );
705+ if (STACK_FLAGS (stack , 1 ) & ZREG_FFI_ZVAL_DEREF ) {
706+ // TODO: try to remove this dereference ???
707+ ref2 = zend_jit_gc_deref (jit , ref2 );
708+ }
709+ ref2 = ir_ADD_OFFSET (ref2 , offsetof(zend_string , val ));
710+ }
711+
712+ ref = ir_CALL_3 (IR_I32 , ir_CONST_FUNC (memcmp ), ref , ref2 , STACK_REF (stack , 2 ));
713+ if (res_addr ) {
714+ /* (-1, 0, 1) = (ret > 0) - (ret < 0) */
715+ ref = ir_SUB_L (ir_SEXT_L (ir_GT (ref , ir_CONST_I32 (0 ))), ir_SEXT_L (ir_LT (ref , ir_CONST_I32 (0 ))));
716+ jit_set_Z_LVAL (jit , res_addr , ref );
717+ jit_set_Z_TYPE_INFO (jit , res_addr , IS_LONG );
718+ }
719+ } else if (TRACE_FRAME_FFI_FUNC (call ) == TRACE_FRAME_FFI_FUNC_MEMSET ) {
720+ ref = STACK_REF (stack , 0 );
721+ if (STACK_FLAGS (stack , 0 ) & ZREG_FFI_ZVAL_DEREF ) {
722+ // TODO: try to remove this dereference ???
723+ ref = zend_jit_gc_deref (jit , ref );
724+ }
725+ ref = jit_FFI_CDATA_PTR (jit , ref );
726+ if (STACK_FLAGS (stack , 0 ) & ZREG_FFI_PTR_LOAD ) {
727+ ref = ir_LOAD_A (ref );
728+ }
729+
730+ ir_CALL_3 (IR_VOID , ir_CONST_FUNC (memset ), ref , STACK_REF (stack , 1 ), STACK_REF (stack , 2 ));
731+ if (res_addr ) {
732+ jit_set_Z_TYPE_INFO (jit , res_addr , IS_NULL );
733+ }
497734 } else {
498735 ZEND_UNREACHABLE ();
499736 }
0 commit comments