@@ -178,6 +178,141 @@ static int zend_jit_ffi_send_val(zend_jit_ctx *jit,
178
178
SET_STACK_TYPE (stack , 1 , IS_LONG , 0 );
179
179
SET_STACK_REF_EX (stack , 1 , ref , 0 );
180
180
}
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
+ }
181
316
} else {
182
317
ZEND_UNREACHABLE ();
183
318
}
@@ -494,6 +629,108 @@ static int zend_jit_ffi_do_call(zend_jit_ctx *jit,
494
629
ir_CALL_3 (IR_VOID , ir_CONST_FC_FUNC (zend_jit_zval_stringl ),
495
630
jit_ZVAL_ADDR (jit , res_addr ), ref , STACK_REF (stack , 1 ));
496
631
}
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
+ }
497
734
} else {
498
735
ZEND_UNREACHABLE ();
499
736
}
0 commit comments