Skip to content

Commit 7a651ba

Browse files
committed
[GR-14211] Be very careful no to raise in PythonLanguage#toString(PythonContext,Object)
PullRequest: graalpython/420
2 parents 0698a59 + f5fe267 commit 7a651ba

File tree

3 files changed

+45
-10
lines changed

3 files changed

+45
-10
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import com.oracle.graal.python.builtins.objects.method.PMethod;
4747
import com.oracle.graal.python.builtins.objects.module.PythonModule;
4848
import com.oracle.graal.python.builtins.objects.object.PythonObject;
49+
import com.oracle.graal.python.builtins.objects.str.PString;
4950
import com.oracle.graal.python.builtins.objects.type.PythonManagedClass;
5051
import com.oracle.graal.python.nodes.BuiltinNames;
5152
import com.oracle.graal.python.nodes.NodeFactory;
@@ -437,16 +438,36 @@ protected SourceSection findSourceLocation(PythonContext context, Object value)
437438
@Override
438439
protected String toString(PythonContext context, Object value) {
439440
final PythonModule builtins = context.getBuiltins();
440-
if (builtins == null) {
441-
// true during initialization
442-
return value.toString();
441+
if (builtins != null) {
442+
// may be null during initialization
443+
Object reprAttribute = builtins.getAttribute(BuiltinNames.REPR);
444+
if (reprAttribute instanceof PBuiltinMethod) {
445+
// may be false if e.g. someone accessed our builtins reflectively
446+
Object reprFunction = ((PBuiltinMethod) reprAttribute).getFunction();
447+
if (reprFunction instanceof PBuiltinFunction) {
448+
// may be false if our builtins were tampered with
449+
Object[] userArgs = PArguments.create(2);
450+
PArguments.setArgument(userArgs, 0, PNone.NONE);
451+
PArguments.setArgument(userArgs, 1, value);
452+
try {
453+
Object result = InvokeNode.invokeUncached((PBuiltinFunction) reprFunction, userArgs);
454+
if (result instanceof String) {
455+
return (String) result;
456+
} else if (result instanceof PString) {
457+
return ((PString) result).getValue();
458+
} else {
459+
// This is illegal for a repr implementation, we ignore the result.
460+
// At this point it's probably difficult to report this properly.
461+
}
462+
} catch (PException e) {
463+
// Fall through to default
464+
}
465+
}
466+
}
443467
}
444-
PBuiltinFunction reprMethod = (PBuiltinFunction) ((PBuiltinMethod) builtins.getAttribute(BuiltinNames.REPR)).getFunction();
445-
Object[] userArgs = PArguments.create(2);
446-
PArguments.setArgument(userArgs, 0, PNone.NONE);
447-
PArguments.setArgument(userArgs, 1, value);
448-
Object res = InvokeNode.create(reprMethod).execute(null, userArgs);
449-
return res.toString();
468+
// This is not a good place to report inconsistencies in any of the above conditions. Just
469+
// return a String
470+
return ((PythonAbstractObject) value).toString();
450471
}
451472

452473
public static TruffleLogger getLogger() {

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 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
@@ -60,4 +60,9 @@ public void setNativeWrapper(DynamicObjectNativeWrapper nativeWrapper) {
6060
assert this.nativeWrapper == null;
6161
this.nativeWrapper = nativeWrapper;
6262
}
63+
64+
@Override
65+
public String toString() {
66+
return "<an abstract python object>";
67+
}
6368
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/call/InvokeNode.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ protected Object doNoKeywords(VirtualFrame frame, PythonObject globals, PCell[]
165165
}
166166

167167
public abstract class InvokeNode extends AbstractInvokeNode {
168+
private static final GenericInvokeNode UNCACHED = new GenericInvokeNode();
168169
@Child private DirectCallNode callNode;
169170
private final PythonObject globals;
170171
private final PCell[] closure;
@@ -199,6 +200,14 @@ public static InvokeNode create(PBuiltinFunction callee) {
199200
return InvokeNodeGen.create(callTarget, null, null, builtin, false);
200201
}
201202

203+
public static Object invokeUncached(PFunction callee, Object[] arguments) {
204+
return UNCACHED.execute(null, callee, arguments);
205+
}
206+
207+
public static Object invokeUncached(PBuiltinFunction callee, Object[] arguments) {
208+
return UNCACHED.execute(null, callee, arguments);
209+
}
210+
202211
@Specialization
203212
protected Object doNoKeywords(VirtualFrame frame, Object[] arguments) {
204213
PArguments.setGlobals(arguments, globals);

0 commit comments

Comments
 (0)