Skip to content

Commit 5372b5b

Browse files
committed
[GR-15913] Avoid interop exceptions.
PullRequest: graalpython/542
2 parents 96bfcc6 + 83cfb0d commit 5372b5b

File tree

3 files changed

+125
-59
lines changed

3 files changed

+125
-59
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,9 +264,9 @@ public void writeArrayElement(long key, Object value,
264264
// it's a sequence, so we assume the index is wrong
265265
throw InvalidArrayIndexException.create(key);
266266
}
267+
} else {
268+
throw UnsupportedMessageException.create();
267269
}
268-
269-
throw UnsupportedMessageException.create();
270270
}
271271

272272
@ExportMessage
@@ -281,9 +281,9 @@ public void removeArrayElement(long key,
281281
// it's a sequence, so we assume the index is wrong
282282
throw InvalidArrayIndexException.create(key);
283283
}
284+
} else {
285+
throw UnsupportedMessageException.create();
284286
}
285-
286-
throw UnsupportedMessageException.create();
287287
}
288288

289289
private static Object iterateToKey(LookupInheritedAttributeNode.Dynamic lookupNextNode, CallNode callNextNode, Object iter, long key) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/AccessForeignItemNodes.java

Lines changed: 116 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public Object doForeignObjectSlice(Object object, PSlice idxSlice,
126126
try {
127127
mslice = materializeSlice(idxSlice, object, lib);
128128
} catch (UnsupportedMessageException e) {
129-
throw raise(AttributeError, "%s instance has no attribute '__getitem__'", object);
129+
throw raiseAttributeError(object);
130130
}
131131
Object[] values = new Object[mslice.length];
132132
for (int i = mslice.start, j = 0; i < mslice.stop; i += mslice.step, j++) {
@@ -138,17 +138,19 @@ public Object doForeignObjectSlice(Object object, PSlice idxSlice,
138138
@Specialization
139139
public Object doForeignKey(Object object, String key,
140140
@CachedLibrary(limit = "3") InteropLibrary lib) {
141-
try {
142-
return lib.readMember(object, key);
143-
} catch (UnsupportedMessageException e) {
144-
if (lib.hasArrayElements(object)) {
145-
throw raise(TypeError, "'%p' object cannot be interpreted as an integer", key);
146-
} else {
147-
throw raise(AttributeError, "%s instance has no attribute '__getitem__'", object);
141+
if (lib.hasMembers(object)) {
142+
if (lib.isMemberReadable(object, key)) {
143+
try {
144+
return lib.readMember(object, key);
145+
} catch (UnsupportedMessageException e) {
146+
throw raiseAttributeErrorDisambiguated(object, key, lib);
147+
} catch (UnknownIdentifierException e) {
148+
// fall through
149+
}
148150
}
149-
} catch (UnknownIdentifierException e) {
150151
throw raise(KeyError, key);
151152
}
153+
throw raiseAttributeErrorDisambiguated(object, key, lib);
152154
}
153155

154156
@Specialization(guards = {"!isSlice(idx)", "!isString(idx)"})
@@ -158,14 +160,36 @@ public Object doForeignObject(Object object, Object idx,
158160
return readForeignValue(object, castIndex.execute(idx), lib);
159161
}
160162

163+
private PException raiseAttributeErrorDisambiguated(Object object, String key, InteropLibrary lib) {
164+
if (lib.hasArrayElements(object)) {
165+
throw raise(TypeError, "'%p' object cannot be interpreted as an integer", key);
166+
} else {
167+
throw raiseAttributeError(object);
168+
}
169+
}
170+
161171
private Object readForeignValue(Object object, long index, InteropLibrary lib) {
162-
try {
163-
return getToPythonNode().executeConvert(lib.readArrayElement(object, index));
164-
} catch (UnsupportedMessageException ex) {
165-
throw raise(AttributeError, "%s instance has no attribute '__getitem__'", object);
166-
} catch (InvalidArrayIndexException ex) {
167-
throw raise(IndexError, "invalid index %s", index);
172+
if (lib.hasArrayElements(object)) {
173+
if (lib.isArrayElementReadable(object, index)) {
174+
try {
175+
return getToPythonNode().executeConvert(lib.readArrayElement(object, index));
176+
} catch (UnsupportedMessageException ex) {
177+
throw raiseAttributeError(object);
178+
} catch (InvalidArrayIndexException ex) {
179+
throw raiseIndexError(index);
180+
}
181+
}
182+
throw raiseIndexError(index);
168183
}
184+
throw raiseAttributeError(object);
185+
}
186+
187+
private PException raiseIndexError(long index) {
188+
return raise(IndexError, "invalid index %s", index);
189+
}
190+
191+
private PException raiseAttributeError(Object object) {
192+
return raise(AttributeError, "%s instance has no attribute '__getitem__'", object);
169193
}
170194

171195
private PForeignToPTypeNode getToPythonNode() {
@@ -207,22 +231,40 @@ public Object doForeignObjectSlice(VirtualFrame frame, Object object, PSlice idx
207231
@Specialization
208232
public Object doForeignKey(Object object, String key, Object value,
209233
@CachedLibrary(limit = "3") InteropLibrary lib) {
210-
try {
211-
lib.writeMember(object, key, value);
212-
return PNone.NONE;
213-
} catch (UnsupportedMessageException e) {
214-
if (lib.hasArrayElements(object)) {
215-
throw raise(TypeError, "'%p' object cannot be interpreted as an integer", key);
216-
} else {
217-
throw raise(AttributeError, "attribute %s is read-only", key);
234+
if (lib.hasMembers(object)) {
235+
if (lib.isMemberWritable(object, key)) {
236+
try {
237+
lib.writeMember(object, key, value);
238+
return PNone.NONE;
239+
} catch (UnsupportedMessageException e) {
240+
throw raiseAttributeReadOnlyDisambiguated(object, key, lib);
241+
} catch (UnknownIdentifierException e) {
242+
throw raiseAttributeError(key);
243+
} catch (UnsupportedTypeException e) {
244+
throw raiseAttributeReadOnly(key);
245+
}
218246
}
219-
} catch (UnknownIdentifierException e) {
220-
throw raise(AttributeError, "foreign object has no attribute '%s'", key);
221-
} catch (UnsupportedTypeException e) {
222-
throw raise(AttributeError, "attribute %s is read-only", key);
247+
throw raiseAttributeReadOnlyDisambiguated(object, key, lib);
248+
}
249+
throw raiseAttributeError(key);
250+
}
251+
252+
private PException raiseAttributeReadOnlyDisambiguated(Object object, String key, InteropLibrary lib) {
253+
if (lib.hasArrayElements(object)) {
254+
throw raise(TypeError, "'%p' object cannot be interpreted as an integer", key);
255+
} else {
256+
throw raiseAttributeReadOnly(key);
223257
}
224258
}
225259

260+
private PException raiseAttributeReadOnly(String key) {
261+
return raise(AttributeError, "attribute %s is read-only", key);
262+
}
263+
264+
private PException raiseAttributeError(String key) {
265+
return raise(AttributeError, "foreign object has no attribute '%s'", key);
266+
}
267+
226268
@Specialization(guards = {"!isSlice(idx)", "!isString(idx)"})
227269
public Object doForeignObject(Object object, Object idx, Object value,
228270
@CachedLibrary(limit = "3") InteropLibrary lib,
@@ -239,13 +281,16 @@ public Object doForeignObject(Object object, Object idx, Object value,
239281
}
240282

241283
private void writeForeignValue(Object object, int idx, Object value, InteropLibrary lib) throws UnsupportedMessageException, UnsupportedTypeException {
242-
if (lib.isArrayElementModifiable(object, idx)) {
243-
try {
244-
lib.writeArrayElement(object, idx, value);
245-
return;
246-
} catch (InvalidArrayIndexException ex) {
247-
throw raise(IndexError, "invalid index %s", idx);
284+
if (lib.hasArrayElements(object)) {
285+
if (lib.isArrayElementWritable(object, idx)) {
286+
try {
287+
lib.writeArrayElement(object, idx, value);
288+
return;
289+
} catch (InvalidArrayIndexException ex) {
290+
// fall through
291+
}
248292
}
293+
throw raise(IndexError, "invalid index %s", idx);
249294
}
250295
throw raise(AttributeError, "%s instance has no attribute '__setitem__'", object);
251296
}
@@ -270,37 +315,58 @@ public Object doForeignObjectSlice(Object object, PSlice idxSlice,
270315
}
271316
return PNone.NONE;
272317
} catch (UnsupportedMessageException e) {
273-
throw raise(AttributeError, "%s instance has no attribute '__delitem__'", object);
318+
throw raiseAttributeError(object);
274319
}
275320
}
276321

277322
@Specialization
278323
public Object doForeignKey(Object object, String key,
279324
@CachedLibrary(limit = "3") InteropLibrary lib) {
280-
try {
281-
lib.removeMember(object, key);
282-
return PNone.NONE;
283-
} catch (UnsupportedMessageException e) {
284-
if (lib.hasArrayElements(object)) {
285-
throw raise(TypeError, "'%p' object cannot be interpreted as an integer", key);
286-
} else {
287-
throw raise(AttributeError, "attribute %s is read-only", key);
325+
if (lib.hasMembers(object)) {
326+
if (lib.isMemberRemovable(object, key)) {
327+
try {
328+
lib.removeMember(object, key);
329+
return PNone.NONE;
330+
} catch (UnsupportedMessageException e) {
331+
throw raiseAttributeReadOnlyDisambiguated(object, key, lib);
332+
} catch (UnknownIdentifierException e) {
333+
throw raiseAttributeError(key);
334+
}
288335
}
289-
} catch (UnknownIdentifierException e) {
290-
throw raise(AttributeError, "foreign object has no attribute '%s'", key);
336+
throw raiseAttributeReadOnlyDisambiguated(object, key, lib);
337+
}
338+
throw raiseAttributeError(key);
339+
}
340+
341+
private PException raiseAttributeError(String key) {
342+
return raise(AttributeError, "foreign object has no attribute '%s'", key);
343+
}
344+
345+
private PException raiseAttributeReadOnlyDisambiguated(Object object, String key, InteropLibrary lib) {
346+
if (lib.hasArrayElements(object)) {
347+
throw raise(TypeError, "'%p' object cannot be interpreted as an integer", key);
348+
} else {
349+
throw raise(AttributeError, "attribute %s is read-only", key);
291350
}
292351
}
293352

294353
@Specialization(guards = "!isSlice(idx)")
295354
public Object doForeignObject(Object object, Object idx,
296355
@Cached CastToIndexNode castIndex,
297356
@CachedLibrary(limit = "3") InteropLibrary lib) {
298-
try {
299-
int convertedIdx = castIndex.execute(idx);
300-
return removeForeignValue(object, convertedIdx, lib);
301-
} catch (UnsupportedMessageException e) {
302-
throw raise(AttributeError, "%s instance has no attribute '__delitem__'", object);
357+
if (lib.hasArrayElements(object)) {
358+
try {
359+
int convertedIdx = castIndex.execute(idx);
360+
return removeForeignValue(object, convertedIdx, lib);
361+
} catch (UnsupportedMessageException e) {
362+
// fall through
363+
}
303364
}
365+
throw raiseAttributeError(object);
366+
}
367+
368+
private PException raiseAttributeError(Object object) {
369+
return raise(AttributeError, "%s instance has no attribute '__delitem__'", object);
304370
}
305371

306372
private Object removeForeignValue(Object object, int idx, InteropLibrary lib) throws UnsupportedMessageException {
@@ -311,7 +377,7 @@ private Object removeForeignValue(Object object, int idx, InteropLibrary lib) th
311377
throw raise(IndexError, "invalid index %s", idx);
312378
}
313379
}
314-
throw raise(AttributeError, "%s instance has no attribute '__delitem__'", object);
380+
throw raiseAttributeError(object);
315381
}
316382

317383
public static RemoveForeignItemNode create() {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignObjectBuiltins.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ public long len(Object self,
181181
}
182182

183183
abstract static class ForeignBinaryNode extends PythonBinaryBuiltinNode {
184-
@Child LookupAndCallBinaryNode op;
184+
@Child private LookupAndCallBinaryNode op;
185185
protected final boolean reverse;
186186

187187
protected ForeignBinaryNode(LookupAndCallBinaryNode op, boolean reverse) {
@@ -423,7 +423,7 @@ abstract static class RFloorDivNode extends ForeignBinaryNode {
423423
}
424424

425425
public abstract static class ForeignBinaryComparisonNode extends PythonBinaryBuiltinNode {
426-
@Child BinaryComparisonNode comparisonNode;
426+
@Child private BinaryComparisonNode comparisonNode;
427427

428428
protected ForeignBinaryComparisonNode(BinaryComparisonNode genericOp) {
429429
this.comparisonNode = genericOp;
@@ -634,7 +634,7 @@ public static CallNode create() {
634634
@Builtin(name = __GETITEM__, minNumOfPositionalArgs = 2)
635635
@GenerateNodeFactory
636636
abstract static class GetitemNode extends PythonBinaryBuiltinNode {
637-
@Child AccessForeignItemNodes.GetForeignItemNode getForeignItemNode = AccessForeignItemNodes.GetForeignItemNode.create();
637+
@Child private AccessForeignItemNodes.GetForeignItemNode getForeignItemNode = AccessForeignItemNodes.GetForeignItemNode.create();
638638

639639
@Specialization
640640
Object doit(Object object, Object key) {
@@ -645,7 +645,7 @@ Object doit(Object object, Object key) {
645645
@Builtin(name = __GETATTR__, minNumOfPositionalArgs = 2)
646646
@GenerateNodeFactory
647647
abstract static class GetattrNode extends PythonBinaryBuiltinNode {
648-
@Child PForeignToPTypeNode toPythonNode = PForeignToPTypeNode.create();
648+
@Child private PForeignToPTypeNode toPythonNode = PForeignToPTypeNode.create();
649649

650650
@Specialization
651651
protected Object doIt(Object object, String member,
@@ -705,7 +705,7 @@ protected PNone doIt(Object object, String key,
705705
@Builtin(name = __DELITEM__, minNumOfPositionalArgs = 2)
706706
@GenerateNodeFactory
707707
abstract static class DelitemNode extends PythonBinaryBuiltinNode {
708-
AccessForeignItemNodes.RemoveForeignItemNode delForeignItemNode = AccessForeignItemNodes.RemoveForeignItemNode.create();
708+
@Child private AccessForeignItemNodes.RemoveForeignItemNode delForeignItemNode = AccessForeignItemNodes.RemoveForeignItemNode.create();
709709

710710
@Specialization
711711
PNone doit(Object object, Object key) {

0 commit comments

Comments
 (0)