@@ -159,76 +159,63 @@ static mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
159
159
}
160
160
161
161
static mp_obj_t list_subscr (mp_obj_t self_in , mp_obj_t index , mp_obj_t value ) {
162
- if (value == MP_OBJ_NULL ) {
163
- // delete
164
- #if MICROPY_PY_BUILTINS_SLICE
165
- if (mp_obj_is_type (index , & mp_type_slice )) {
166
- mp_obj_list_t * self = MP_OBJ_TO_PTR (self_in );
167
- mp_bound_slice_t slice ;
168
- if (!mp_seq_get_fast_slice_indexes (self -> len , index , & slice )) {
169
- mp_raise_NotImplementedError (NULL );
162
+ #if MICROPY_PY_BUILTINS_SLICE
163
+ if (mp_obj_is_type (index , & mp_type_slice )) {
164
+ mp_obj_list_t * self = MP_OBJ_TO_PTR (self_in );
165
+ mp_bound_slice_t slice ;
166
+ bool fast = mp_seq_get_fast_slice_indexes (self -> len , index , & slice );
167
+ if (value == MP_OBJ_SENTINEL ) {
168
+ // load
169
+ if (!fast ) {
170
+ return mp_seq_extract_slice (self -> items , & slice );
170
171
}
171
-
172
- mp_int_t len_adj = slice .start - slice .stop ;
173
- assert (len_adj <= 0 );
174
- mp_seq_replace_slice_no_grow (self -> items , self -> len , slice .start , slice .stop , self -> items /*NULL*/ , 0 , sizeof (* self -> items ));
172
+ mp_obj_list_t * res = list_new (slice .stop - slice .start );
173
+ mp_seq_copy (res -> items , self -> items + slice .start , res -> len , mp_obj_t );
174
+ return MP_OBJ_FROM_PTR (res );
175
+ }
176
+ // assign/delete
177
+ if (value == MP_OBJ_NULL ) {
178
+ // delete is equivalent to slice assignment of an empty sequence
179
+ value = mp_const_empty_tuple ;
180
+ }
181
+ if (!fast ) {
182
+ mp_raise_NotImplementedError (NULL );
183
+ }
184
+ size_t value_len ;
185
+ mp_obj_t * value_items ;
186
+ mp_obj_get_array (value , & value_len , & value_items );
187
+ mp_int_t len_adj = value_len - (slice .stop - slice .start );
188
+ if (len_adj > 0 ) {
189
+ if (self -> len + len_adj > self -> alloc ) {
190
+ // TODO: Might optimize memory copies here by checking if block can
191
+ // be grown inplace or not
192
+ self -> items = m_renew (mp_obj_t , self -> items , self -> alloc , self -> len + len_adj );
193
+ self -> alloc = self -> len + len_adj ;
194
+ }
195
+ mp_seq_replace_slice_grow_inplace (self -> items , self -> len ,
196
+ slice .start , slice .stop , value_items , value_len , len_adj , sizeof (* self -> items ));
197
+ } else {
198
+ mp_seq_replace_slice_no_grow (self -> items , self -> len ,
199
+ slice .start , slice .stop , value_items , value_len , sizeof (* self -> items ));
175
200
// Clear "freed" elements at the end of list
176
201
mp_seq_clear (self -> items , self -> len + len_adj , self -> len , sizeof (* self -> items ));
177
- self -> len += len_adj ;
178
- return mp_const_none ;
202
+ // TODO: apply allocation policy re: alloc_size
179
203
}
180
- #endif
204
+ self -> len += len_adj ;
205
+ return mp_const_none ;
206
+ }
207
+ #endif
208
+ if (value == MP_OBJ_NULL ) {
209
+ // delete
181
210
mp_obj_t args [2 ] = {self_in , index };
182
211
list_pop (2 , args );
183
212
return mp_const_none ;
184
213
} else if (value == MP_OBJ_SENTINEL ) {
185
214
// load
186
215
mp_obj_list_t * self = MP_OBJ_TO_PTR (self_in );
187
- #if MICROPY_PY_BUILTINS_SLICE
188
- if (mp_obj_is_type (index , & mp_type_slice )) {
189
- mp_bound_slice_t slice ;
190
- if (!mp_seq_get_fast_slice_indexes (self -> len , index , & slice )) {
191
- return mp_seq_extract_slice (self -> items , & slice );
192
- }
193
- mp_obj_list_t * res = list_new (slice .stop - slice .start );
194
- mp_seq_copy (res -> items , self -> items + slice .start , res -> len , mp_obj_t );
195
- return MP_OBJ_FROM_PTR (res );
196
- }
197
- #endif
198
216
size_t index_val = mp_get_index (self -> base .type , self -> len , index , false);
199
217
return self -> items [index_val ];
200
218
} else {
201
- #if MICROPY_PY_BUILTINS_SLICE
202
- if (mp_obj_is_type (index , & mp_type_slice )) {
203
- mp_obj_list_t * self = MP_OBJ_TO_PTR (self_in );
204
- size_t value_len ;
205
- mp_obj_t * value_items ;
206
- mp_obj_get_array (value , & value_len , & value_items );
207
- mp_bound_slice_t slice_out ;
208
- if (!mp_seq_get_fast_slice_indexes (self -> len , index , & slice_out )) {
209
- mp_raise_NotImplementedError (NULL );
210
- }
211
- mp_int_t len_adj = value_len - (slice_out .stop - slice_out .start );
212
- if (len_adj > 0 ) {
213
- if (self -> len + len_adj > self -> alloc ) {
214
- // TODO: Might optimize memory copies here by checking if block can
215
- // be grown inplace or not
216
- self -> items = m_renew (mp_obj_t , self -> items , self -> alloc , self -> len + len_adj );
217
- self -> alloc = self -> len + len_adj ;
218
- }
219
- mp_seq_replace_slice_grow_inplace (self -> items , self -> len ,
220
- slice_out .start , slice_out .stop , value_items , value_len , len_adj , sizeof (* self -> items ));
221
- } else {
222
- mp_seq_replace_slice_no_grow (self -> items , self -> len ,
223
- slice_out .start , slice_out .stop , value_items , value_len , sizeof (* self -> items ));
224
- // Clear "freed" elements at the end of list
225
- mp_seq_clear (self -> items , self -> len + len_adj , self -> len , sizeof (* self -> items ));
226
- // TODO: apply allocation policy re: alloc_size
227
- }
228
- self -> len += len_adj ;
229
- return mp_const_none ;
230
- }
231
- #endif
232
219
mp_obj_list_store (self_in , index , value );
233
220
return mp_const_none ;
234
221
}
0 commit comments