Skip to content

Commit b92e315

Browse files
fangerercosminbasca
authored andcommitted
Fix: __setitem__ should not mutate deque state
1 parent 6cf03cb commit b92e315

File tree

2 files changed

+29
-25
lines changed

2 files changed

+29
-25
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/DequeBuiltins.java

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion;
7575
import com.oracle.graal.python.builtins.Builtin;
7676
import com.oracle.graal.python.builtins.CoreFunctions;
77+
import com.oracle.graal.python.builtins.Python3Core;
7778
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
7879
import com.oracle.graal.python.builtins.PythonBuiltins;
7980
import com.oracle.graal.python.builtins.objects.PNone;
@@ -117,7 +118,6 @@
117118
import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode;
118119
import com.oracle.graal.python.nodes.util.CastToJavaStringNode;
119120
import com.oracle.graal.python.runtime.PythonContext;
120-
import com.oracle.graal.python.builtins.Python3Core;
121121
import com.oracle.graal.python.runtime.exception.PException;
122122
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
123123
import com.oracle.truffle.api.CompilerDirectives;
@@ -853,31 +853,9 @@ protected ArgumentClinicProvider getArgumentClinic() {
853853
static PNone doGeneric(PDeque self, int idx, Object value,
854854
@Cached NormalizeIndexCustomMessageNode normalizeIndexNode) {
855855
int normIdx = normalizeIndexNode.execute(idx, self.getSize(), ErrorMessages.DEQUE_INDEX_OUT_OF_RANGE);
856-
doSetItem(self, normIdx, value);
856+
self.setItem(normIdx, value != PNone.NO_VALUE ? value : null);
857857
return PNone.NONE;
858858
}
859-
860-
@TruffleBoundary
861-
static void doSetItem(PDeque self, int idx, Object value) {
862-
assert 0 <= idx && idx < self.getSize();
863-
int n = self.getSize() - idx - 1;
864-
Object[] savedItems = new Object[n];
865-
for (int i = 0; i < savedItems.length; i++) {
866-
savedItems[i] = self.pop();
867-
}
868-
// this removes the item we want to replace
869-
self.pop();
870-
assert self.getSize() == idx;
871-
if (value != PNone.NO_VALUE) {
872-
self.append(value);
873-
}
874-
875-
// re-add saved items
876-
for (int i = savedItems.length - 1; i >= 0; i--) {
877-
self.append(savedItems[i]);
878-
}
879-
assert value != PNone.NO_VALUE && self.getSize() == n + idx + 1 || value == PNone.NO_VALUE && self.getSize() == n + idx;
880-
}
881859
}
882860

883861
@Builtin(name = __DELITEM__, minNumOfPositionalArgs = 2, parameterNames = {"$self", "n"})
@@ -894,7 +872,7 @@ protected ArgumentClinicProvider getArgumentClinic() {
894872
static PNone doGeneric(PDeque self, int idx,
895873
@Cached NormalizeIndexCustomMessageNode normalizeIndexNode) {
896874
int normIdx = normalizeIndexNode.execute(idx, self.getSize(), ErrorMessages.DEQUE_INDEX_OUT_OF_RANGE);
897-
DequeSetItemNode.doSetItem(self, normIdx, PNone.NO_VALUE);
875+
self.setItem(normIdx, null);
898876
return PNone.NONE;
899877
}
900878
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/deque/PDeque.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,32 @@ public void clear() {
166166
state++;
167167
}
168168

169+
@TruffleBoundary
170+
public void setItem(int idx, Object value) {
171+
assert 0 <= idx && idx < data.size();
172+
int n = data.size() - idx - 1;
173+
Object[] savedItems = new Object[n];
174+
for (int i = 0; i < savedItems.length; i++) {
175+
savedItems[i] = data.pollLast();
176+
}
177+
// this removes the item we want to replace
178+
data.pollLast();
179+
assert data.size() == idx;
180+
if (value != null) {
181+
data.addLast(value);
182+
} else {
183+
// removal case: this alters the number of elements, so modify the state
184+
state++;
185+
}
186+
187+
// re-add saved items
188+
for (int i = savedItems.length - 1; i >= 0; i--) {
189+
data.addLast(savedItems[i]);
190+
}
191+
assert maxLength == -1 || data.size() <= maxLength;
192+
assert value != null && data.size() == n + idx + 1 || value == null && data.size() == n + idx;
193+
}
194+
169195
public int getState() {
170196
return state;
171197
}

0 commit comments

Comments
 (0)