This commit adds a fast-path optimisation for when a BUILD_SLICE is immediately followed by a LOAD/STORE_SUBSCR for a native type, to avoid needing to allocate the slice on the heap. In some cases (e.g. `a[1:3] = x`) this can result in no allocations at all. We can't do this for instance types because the get/set/delattr implementation may keep a reference to the slice. Adds more tests to the basic slice tests to ensure that a stack-allocated slice never makes it to Python, and also a heapalloc test that verifies (when using bytecode) that assigning to a slice is no-alloc. This work was funded through GitHub Sponsors. Signed-off-by: Jim Mussared <jim.mussared@gmail.com> Signed-off-by: Damien George <damien@micropython.org>
44 lines
837 B
Python
44 lines
837 B
Python
# test builtin slice
|
|
|
|
# ensures that slices passed to user types are heap-allocated and can be
|
|
# safely stored as well as not overriden by subsequent slices.
|
|
|
|
# print slice
|
|
class A:
|
|
def __getitem__(self, idx):
|
|
print("get", idx)
|
|
print("abc"[1:])
|
|
print("get", idx)
|
|
return idx
|
|
|
|
def __setitem__(self, idx, value):
|
|
print("set", idx)
|
|
print("abc"[1:])
|
|
print("set", idx)
|
|
self.saved_idx = idx
|
|
return idx
|
|
|
|
def __delitem__(self, idx):
|
|
print("del", idx)
|
|
print("abc"[1:])
|
|
print("del", idx)
|
|
return idx
|
|
|
|
|
|
a = A()
|
|
s = a[1:2:3]
|
|
a[4:5:6] = s
|
|
del a[7:8:9]
|
|
|
|
print(a.saved_idx)
|
|
|
|
# nested slicing
|
|
print(A()[1 : A()[A()[2:3:4] : 5]])
|
|
|
|
# tuple slicing
|
|
a[1:2, 4:5, 7:8]
|
|
a[1, 4:5, 7:8, 2]
|
|
a[1:2, a[3:4], 5:6]
|
|
|
|
# check type
|
|
print(type(s) is slice)
|