Skip to content

Commit 68305a7

Browse files
committed
Migrate sq_ass_item and mp_ass_subscript to new slots
1 parent 542f72d commit 68305a7

File tree

26 files changed

+1186
-471
lines changed

26 files changed

+1186
-471
lines changed

graalpython/com.oracle.graal.python.annotations/src/com/oracle/graal/python/annotations/Slot.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ enum SlotKind {
125125
sq_length("__len__"),
126126
/** sequence item: read element at index */
127127
sq_item("__getitem__"),
128+
/** write sequence element at index */
129+
sq_ass_item("__setitem__"),
128130
/** seq + seq, nb_add is tried before */
129131
sq_concat("__add__"),
130132
/** seq * number, nb_multiply is tried before */
@@ -133,6 +135,8 @@ enum SlotKind {
133135
mp_length("__len__"),
134136
/** mapping subscript, e.g. o[key], o[i:j] */
135137
mp_subscript("__getitem__"),
138+
/** o[key] = value */
139+
mp_ass_subscript("__setitem__"),
136140
/** type descriptor get */
137141
tp_descr_get("__get__"),
138142
/** type descriptor set/delete */

graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/SlotsMapping.java

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ static String getSlotBaseClass(Slot s) {
5858
case sq_concat -> "TpSlotBinaryFunc.TpSlotSqConcat";
5959
case sq_length, mp_length -> "TpSlotLen.TpSlotLenBuiltin" + getSuffix(s.isComplex());
6060
case sq_item, sq_repeat -> "TpSlotSizeArgFun.TpSlotSizeArgFunBuiltin";
61+
case sq_ass_item -> "TpSlotSqAssItem.TpSlotSqAssItemBuiltin";
6162
case mp_subscript -> "TpSlotBinaryFunc.TpSlotMpSubscript";
63+
case mp_ass_subscript -> "TpSlotMpAssSubscript.TpSlotMpAssSubscriptBuiltin";
6264
case tp_getattro -> "TpSlotGetAttr.TpSlotGetAttrBuiltin";
6365
case tp_descr_get -> "TpSlotDescrGet.TpSlotDescrGetBuiltin" + getSuffix(s.isComplex());
6466
case tp_descr_set -> "TpSlotDescrSet.TpSlotDescrSetBuiltin";
@@ -76,8 +78,10 @@ static String getSlotNodeBaseClass(Slot s) {
7678
case sq_concat -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.SqConcatBuiltinNode";
7779
case sq_length, mp_length -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.LenBuiltinNode";
7880
case sq_item -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqItemBuiltinNode";
81+
case sq_ass_item -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqAssItem.SqAssItemBuiltinNode";
7982
case sq_repeat -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqRepeatBuiltinNode";
8083
case mp_subscript -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.MpSubscriptBuiltinNode";
84+
case mp_ass_subscript -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotMpAssSubscript.MpAssSubscriptBuiltinNode";
8185
case tp_getattro -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotGetAttr.GetAttrBuiltinNode";
8286
case tp_descr_set -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotDescrSet.DescrSetBuiltinNode";
8387
case tp_setattro -> "com.oracle.graal.python.builtins.objects.type.slots.TpSlotSetAttr.SetAttrBuiltinNode";
@@ -89,31 +93,21 @@ static String getUncachedExecuteSignature(SlotKind s) {
8993
case nb_bool -> "boolean executeUncached(Object self)";
9094
case tp_descr_get -> "Object executeUncached(Object self, Object obj, Object type)";
9195
case sq_length, mp_length -> "int executeUncached(Object self)";
92-
case tp_getattro, tp_descr_set, tp_setattro, sq_item, mp_subscript, sq_concat, sq_repeat,
93-
nb_add, nb_subtract, nb_multiply, nb_remainder, nb_divmod, nb_lshift, nb_rshift,
94-
nb_and, nb_xor, nb_or, nb_floor_divide, nb_true_divide, nb_matrix_multiply ->
95-
throw new AssertionError("Should not reach here: should be always complex");
96+
default -> throw new AssertionError("Should not reach here: should be always complex");
9697
};
9798
}
9899

99100
static boolean supportsComplex(SlotKind s) {
100101
return switch (s) {
101102
case nb_bool -> false;
102-
case sq_length, mp_length, tp_getattro, tp_descr_get, tp_descr_set,
103-
tp_setattro, sq_item, mp_subscript, sq_concat, sq_repeat,
104-
nb_add, nb_subtract, nb_multiply, nb_remainder, nb_divmod, nb_lshift, nb_rshift,
105-
nb_and, nb_xor, nb_or, nb_floor_divide, nb_true_divide, nb_matrix_multiply ->
106-
true;
103+
default -> true;
107104
};
108105
}
109106

110107
static boolean supportsSimple(SlotKind s) {
111108
return switch (s) {
112109
case nb_bool, sq_length, mp_length, tp_descr_get -> true;
113-
case tp_getattro, tp_descr_set, tp_setattro, sq_item, mp_subscript, sq_concat, sq_repeat,
114-
nb_add, nb_subtract, nb_multiply, nb_remainder, nb_divmod, nb_lshift, nb_rshift,
115-
nb_and, nb_xor, nb_or, nb_floor_divide, nb_true_divide, nb_matrix_multiply ->
116-
false;
110+
default -> false;
117111
};
118112
}
119113

@@ -122,10 +116,7 @@ static String getUncachedExecuteCall(SlotKind s) {
122116
case nb_bool -> "executeBool(null, self)";
123117
case sq_length, mp_length -> "executeInt(null, self)";
124118
case tp_descr_get -> "execute(null, self, obj, type)";
125-
case tp_getattro, tp_descr_set, tp_setattro, sq_item, mp_subscript, sq_concat, sq_repeat,
126-
nb_add, nb_subtract, nb_multiply, nb_remainder, nb_divmod, nb_lshift, nb_rshift,
127-
nb_and, nb_xor, nb_or, nb_floor_divide, nb_true_divide, nb_matrix_multiply ->
128-
throw new AssertionError("Should not reach here: should be always complex");
119+
default -> throw new AssertionError("Should not reach here: should be always complex");
129120
};
130121
}
131122

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextDictBuiltins.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -95,12 +95,12 @@
9595
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItemWithHash;
9696
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemNode;
9797
import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.ClearNode;
98-
import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.DelItemNode;
9998
import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.PopNode;
10099
import com.oracle.graal.python.builtins.objects.dict.DictNodes;
101100
import com.oracle.graal.python.builtins.objects.dict.PDict;
102101
import com.oracle.graal.python.builtins.objects.ints.PInt;
103102
import com.oracle.graal.python.builtins.objects.list.PList;
103+
import com.oracle.graal.python.lib.PyDictDelItem;
104104
import com.oracle.graal.python.lib.PyDictSetDefault;
105105
import com.oracle.graal.python.lib.PyObjectGetAttr;
106106
import com.oracle.graal.python.lib.PyObjectHashNode;
@@ -427,8 +427,9 @@ public Object fallback(Object dict, @SuppressWarnings("unused") Object key, @Sup
427427
abstract static class PyDict_DelItem extends CApiBinaryBuiltinNode {
428428
@Specialization
429429
static int delItem(PDict dict, Object key,
430-
@Cached DelItemNode delItemNode) {
431-
delItemNode.execute(null, dict, key);
430+
@Bind("this") Node inliningTarget,
431+
@Cached PyDictDelItem delItemNode) {
432+
delItemNode.execute(null, inliningTarget, dict, key);
432433
return 0;
433434
}
434435

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -92,7 +92,6 @@
9292
import com.oracle.graal.python.builtins.objects.cext.common.NativePointer;
9393
import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess;
9494
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageGetItem;
95-
import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.SetItemNode;
9695
import com.oracle.graal.python.builtins.objects.dict.PDict;
9796
import com.oracle.graal.python.builtins.objects.exception.ExceptionNodes;
9897
import com.oracle.graal.python.builtins.objects.exception.GetEscapedExceptionNode;
@@ -104,6 +103,7 @@
104103
import com.oracle.graal.python.builtins.objects.traceback.PTraceback;
105104
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
106105
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode;
106+
import com.oracle.graal.python.lib.PyDictSetItem;
107107
import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs;
108108
import com.oracle.graal.python.lib.PyObjectGetAttr;
109109
import com.oracle.graal.python.lib.PyObjectLookupAttr;
@@ -337,7 +337,7 @@ static Object newEx(TruffleString name, Object base, Object dict,
337337
@Cached TruffleString.IndexOfCodePointNode indexOfCodepointNode,
338338
@Cached TruffleString.CodePointLengthNode codePointLengthNode,
339339
@Cached TruffleString.SubstringNode substringNode,
340-
@Cached SetItemNode setItemNode,
340+
@Cached PyDictSetItem setItemNode,
341341
@Cached TypeNode typeNode,
342342
@Cached InlinedBranchProfile notDotProfile,
343343
@Cached InlinedBranchProfile notModuleProfile,
@@ -358,7 +358,7 @@ static Object newEx(TruffleString name, Object base, Object dict,
358358
}
359359
if (getItem.execute(null, inliningTarget, ((PDict) dict).getDictStorage(), base) == null) {
360360
notModuleProfile.enter(inliningTarget);
361-
setItemNode.execute(null, dict, T___MODULE__, substringNode.execute(name, 0, dotIdx, TS_ENCODING, false));
361+
setItemNode.execute(null, inliningTarget, (PDict) dict, T___MODULE__, substringNode.execute(name, 0, dotIdx, TS_ENCODING, false));
362362
}
363363
PTuple bases;
364364
if (baseProfile.profile(inliningTarget, base instanceof PTuple)) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextListBuiltins.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -212,7 +212,7 @@ abstract static class PyList_SetSlice extends CApiQuaternaryBuiltinNode {
212212
@Specialization
213213
static int getSlice(PList list, Object iLow, Object iHigh, Object s,
214214
@Bind("this") Node inliningTarget,
215-
@Cached com.oracle.graal.python.builtins.objects.list.ListBuiltins.SetItemNode setItemNode,
215+
@Cached ListBuiltins.SetSubscriptNode setItemNode,
216216
@Cached PySliceNew sliceNode) {
217217
setItemNode.execute(null, list, sliceNode.execute(inliningTarget, iLow, iHigh, PNone.NONE), s);
218218
return 0;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCArrayBuiltins.java

Lines changed: 37 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -50,7 +50,6 @@
5050
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___CLASS_GETITEM__;
5151
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___INIT__;
5252
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___NEW__;
53-
import static com.oracle.graal.python.nodes.SpecialMethodNames.J___SETITEM__;
5453
import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING;
5554
import static com.oracle.graal.python.runtime.exception.PythonErrorType.IndexError;
5655
import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
@@ -81,7 +80,9 @@
8180
import com.oracle.graal.python.builtins.objects.type.TpSlots;
8281
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotBinaryFunc.MpSubscriptBuiltinNode;
8382
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.LenBuiltinNode;
83+
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotMpAssSubscript.MpAssSubscriptBuiltinNode;
8484
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqItemBuiltinNode;
85+
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqAssItem;
8586
import com.oracle.graal.python.lib.PyIndexCheckNode;
8687
import com.oracle.graal.python.lib.PyNumberAsSizeNode;
8788
import com.oracle.graal.python.lib.PyNumberIndexNode;
@@ -93,7 +94,6 @@
9394
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
9495
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
9596
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
96-
import com.oracle.graal.python.nodes.function.builtins.PythonTernaryBuiltinNode;
9797
import com.oracle.graal.python.runtime.object.PythonObjectFactory;
9898
import com.oracle.graal.python.util.PythonUtils;
9999
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
@@ -156,16 +156,16 @@ static Object Array_init(VirtualFrame frame, CDataObject self, Object[] args, @S
156156
}
157157
}
158158

159-
@Builtin(name = J___SETITEM__, minNumOfPositionalArgs = 3)
159+
@Slot(value = SlotKind.sq_ass_item, isComplex = true)
160160
@GenerateNodeFactory
161-
abstract static class PyCArraySetItemNode extends PythonTernaryBuiltinNode {
161+
abstract static class PyCArraySetItemNode extends TpSlotSqAssItem.SqAssItemBuiltinNode {
162162

163-
@Specialization(guards = "!isPNone(value)")
164-
static Object Array_ass_item(VirtualFrame frame, CDataObject self, int index, Object value,
163+
@Specialization(guards = "!isNoValue(value)")
164+
static void Array_ass_item(VirtualFrame frame, CDataObject self, int index, Object value,
165165
@Bind("this") Node inliningTarget,
166-
@Exclusive @Cached PyObjectStgDictNode pyObjectStgDictNode,
167-
@Shared @Cached PyCDataSetNode pyCDataSetNode,
168-
@Exclusive @Cached PRaiseNode.Lazy raiseNode) {
166+
@Cached PyObjectStgDictNode pyObjectStgDictNode,
167+
@Cached PyCDataSetNode pyCDataSetNode,
168+
@Cached PRaiseNode.Lazy raiseNode) {
169169
StgDictObject stgdict = pyObjectStgDictNode.execute(inliningTarget, self);
170170
assert stgdict != null : "Cannot be NULL for array object instances";
171171
if (index < 0 || index >= stgdict.length) {
@@ -176,66 +176,64 @@ static Object Array_ass_item(VirtualFrame frame, CDataObject self, int index, Ob
176176
int offset = index * size;
177177

178178
pyCDataSetNode.execute(frame, self, stgdict.proto, stgdict.setfunc, value, index, size, self.b_ptr.withOffset(offset));
179-
return PNone.NONE;
180179
}
181180

182181
@SuppressWarnings("unused")
183-
@Specialization(guards = {"!isPNone(value)", "!isPSlice(item)"})
184-
static Object Array_ass_subscript(VirtualFrame frame, CDataObject self, Object item, Object value,
182+
@Specialization(guards = "isNoValue(value)")
183+
static void error(CDataObject self, int index, PNone value,
184+
@Cached PRaiseNode raiseNode) {
185+
throw raiseNode.raise(TypeError, ARRAY_DOES_NOT_SUPPORT_ITEM_DELETION);
186+
}
187+
}
188+
189+
@Slot(value = SlotKind.mp_ass_subscript, isComplex = true)
190+
@GenerateNodeFactory
191+
abstract static class PyCArraySetSubscriptNode extends MpAssSubscriptBuiltinNode {
192+
193+
@Specialization(guards = {"!isNoValue(value)", "!isPSlice(indexObj)"})
194+
static void Array_ass_subscript(VirtualFrame frame, CDataObject self, Object indexObj, Object value,
185195
@Bind("this") Node inliningTarget,
186196
@Cached PyIndexCheckNode indexCheckNode,
187197
@Cached PyNumberAsSizeNode asSint,
188-
@Exclusive @Cached PyObjectStgDictNode pyObjectStgDictNode,
189-
@Shared @Cached PyCDataSetNode pyCDataSetNode,
198+
@Shared @Cached PyCArraySetItemNode setItemNode,
190199
@Exclusive @Cached PRaiseNode.Lazy raiseNode) {
191-
if (indexCheckNode.execute(inliningTarget, item)) {
192-
int i = asSint.executeExact(frame, inliningTarget, item, IndexError);
193-
if (i < 0) {
194-
i += self.b_length;
200+
if (indexCheckNode.execute(inliningTarget, indexObj)) {
201+
int index = asSint.executeExact(frame, inliningTarget, indexObj, IndexError);
202+
if (index < 0) {
203+
index += self.b_length;
195204
}
196-
Array_ass_item(frame, self, i, value, inliningTarget,
197-
pyObjectStgDictNode,
198-
pyCDataSetNode,
199-
raiseNode);
205+
setItemNode.executeIntKey(frame, self, index, value);
200206
} else {
201207
throw raiseNode.get(inliningTarget).raise(TypeError, INDICES_MUST_BE_INTEGER);
202208
}
203-
return PNone.NONE;
204209
}
205210

206-
@SuppressWarnings("unused")
207-
@Specialization(guards = "!isPNone(value)")
208-
static Object Array_ass_subscript(VirtualFrame frame, CDataObject self, PSlice slice, Object value,
211+
@Specialization(guards = "!isNoValue(value)")
212+
static void Array_ass_subscript(VirtualFrame frame, CDataObject self, PSlice slice, Object value,
209213
@Bind("this") Node inliningTarget,
210214
@Cached PyObjectSizeNode pySequenceLength,
211215
@Cached PyObjectGetItem pySequenceGetItem,
212216
@Cached SliceUnpack sliceUnpack,
213217
@Cached AdjustIndices adjustIndices,
214-
@Exclusive @Cached PyObjectStgDictNode pyObjectStgDictNode,
215-
@Shared @Cached PyCDataSetNode pyCDataSetNode,
218+
@Shared @Cached PyCArraySetItemNode setItemNode,
216219
@Exclusive @Cached PRaiseNode.Lazy raiseNode) {
217220
PSlice.SliceInfo sliceInfo = adjustIndices.execute(inliningTarget, self.b_length, sliceUnpack.execute(inliningTarget, slice));
218-
int start = sliceInfo.start, stop = sliceInfo.stop, step = sliceInfo.step;
221+
int start = sliceInfo.start, step = sliceInfo.step;
219222
int slicelen = sliceInfo.sliceLength;
220-
// if ((step < 0 && start < stop) || (step > 0 && start > stop))
221-
// stop = start;
222223

223224
int otherlen = pySequenceLength.execute(frame, inliningTarget, value);
224225
if (otherlen != slicelen) {
225226
throw raiseNode.get(inliningTarget).raise(ValueError, CAN_ONLY_ASSIGN_SEQUENCE_OF_SAME_SIZE);
226227
}
227228
for (int cur = start, i = 0; i < otherlen; cur += step, i++) {
228-
Array_ass_item(frame, self, cur, pySequenceGetItem.execute(frame, inliningTarget, value, i), inliningTarget,
229-
pyObjectStgDictNode,
230-
pyCDataSetNode,
231-
raiseNode);
229+
Object item = pySequenceGetItem.execute(frame, inliningTarget, value, i);
230+
setItemNode.executeIntKey(frame, self, cur, item);
232231
}
233-
return PNone.NONE;
234232
}
235233

236234
@SuppressWarnings("unused")
237-
@Specialization
238-
static Object error(CDataObject self, Object item, PNone value,
235+
@Specialization(guards = "isNoValue(value)")
236+
static void error(CDataObject self, Object index, PNone value,
239237
@Cached PRaiseNode raiseNode) {
240238
throw raiseNode.raise(TypeError, ARRAY_DOES_NOT_SUPPORT_ITEM_DELETION);
241239
}

0 commit comments

Comments
 (0)