@@ -1182,6 +1182,67 @@ static void sccp_visit_instr(scdf_ctx *scdf, zend_op *opline, zend_ssa_op *ssa_o
11821182 }
11831183 return ;
11841184 }
1185+ case ZEND_ARRAY_DUP : {
1186+ SET_RESULT (result , op1 );
1187+ return ;
1188+ }
1189+ case ZEND_ARRAY_SET_PLACEHOLDER : {
1190+ zval * result = & ctx -> values [ssa_op -> result_use ];
1191+
1192+ SKIP_IF_TOP (result );
1193+ SKIP_IF_TOP (op1 );
1194+
1195+ #if 1
1196+ /* FIXME: See below. */
1197+ if (IS_BOT (result )) {
1198+ SET_RESULT_BOT (result );
1199+ return ;
1200+ }
1201+ #else
1202+ ZEND_ASSERT (!IS_BOT (result ));
1203+ #endif
1204+
1205+ /* FIXME: Avoid dup-ing the array in every step. */
1206+ zend_array * array = zend_array_dup (Z_ARRVAL_P (result ));
1207+ zval * element = (zval * )((uintptr_t )array -> arData + opline -> op2 .num );
1208+
1209+ zval tmp ;
1210+ ZVAL_ARR (& tmp , array );
1211+
1212+ if (IS_BOT (op1 )) {
1213+ #if 1
1214+ /* FIXME: Handle partial arrays. Deleting hashes is problematic
1215+ * because it changes the offsets for the placeholders. */
1216+ SET_RESULT_BOT (result );
1217+ zval_ptr_dtor_nogc (& tmp );
1218+ return ;
1219+ #else
1220+ /* Remove unknown index and mark array as partial. */
1221+ if (HT_IS_PACKED (array )) {
1222+ zval_ptr_dtor (element );
1223+ ZVAL_UNDEF (element );
1224+ } else {
1225+ Bucket * bucket = (Bucket * )((uintptr_t )element - XtOffsetOf (Bucket , val ));
1226+ if (bucket -> key ) {
1227+ zend_hash_del (array , bucket -> key );
1228+ } else {
1229+ zend_hash_index_del (array , bucket -> h );
1230+ }
1231+ }
1232+ MAKE_PARTIAL_ARRAY (& tmp );
1233+ #endif
1234+ } else {
1235+ ZVAL_COPY (element , op1 );
1236+ if (IS_PARTIAL_ARRAY (op1 )) {
1237+ MAKE_PARTIAL_ARRAY (& tmp );
1238+ }
1239+ }
1240+
1241+
1242+ SET_RESULT (result , & tmp );
1243+ zval_ptr_dtor_nogc (& tmp );
1244+ return ;
1245+ }
11851246 case ZEND_ADD_ARRAY_UNPACK : {
11861247 zval * result = & ctx -> values [ssa_op -> result_use ];
11871248 if (IS_BOT (result ) || IS_BOT (op1 )) {
@@ -2196,7 +2257,9 @@ static int try_remove_definition(sccp_ctx *ctx, int var_num, zend_ssa_var *var,
21962257 && opline -> opcode != ZEND_ROPE_ADD
21972258 && opline -> opcode != ZEND_INIT_ARRAY
21982259 && opline -> opcode != ZEND_ADD_ARRAY_ELEMENT
2199- && opline -> opcode != ZEND_ADD_ARRAY_UNPACK ) {
2260+ && opline -> opcode != ZEND_ADD_ARRAY_UNPACK
2261+ && opline -> opcode != ZEND_ARRAY_DUP
2262+ && opline -> opcode != ZEND_ARRAY_SET_PLACEHOLDER ) {
22002263 /* Replace with QM_ASSIGN */
22012264 uint8_t old_type = opline -> result_type ;
22022265 uint32_t old_var = opline -> result .var ;
0 commit comments