@@ -159,76 +159,63 @@ static mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
159159}
160160
161161static 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 );
170171 }
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 ));
175200 // Clear "freed" elements at the end of list
176201 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
179203 }
180- #endif
204+ self -> len += len_adj ;
205+ return mp_const_none ;
206+ }
207+ #endif
208+ if (value == MP_OBJ_NULL ) {
209+ // delete
181210 mp_obj_t args [2 ] = {self_in , index };
182211 list_pop (2 , args );
183212 return mp_const_none ;
184213 } else if (value == MP_OBJ_SENTINEL ) {
185214 // load
186215 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
198216 size_t index_val = mp_get_index (self -> base .type , self -> len , index , false);
199217 return self -> items [index_val ];
200218 } 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
232219 mp_obj_list_store (self_in , index , value );
233220 return mp_const_none ;
234221 }
0 commit comments