|
46 | 46 | import com.oracle.graal.python.builtins.objects.method.PMethod;
|
47 | 47 | import com.oracle.graal.python.builtins.objects.module.PythonModule;
|
48 | 48 | import com.oracle.graal.python.builtins.objects.object.PythonObject;
|
| 49 | +import com.oracle.graal.python.builtins.objects.str.PString; |
49 | 50 | import com.oracle.graal.python.builtins.objects.type.PythonManagedClass;
|
50 | 51 | import com.oracle.graal.python.nodes.BuiltinNames;
|
51 | 52 | import com.oracle.graal.python.nodes.NodeFactory;
|
@@ -437,16 +438,36 @@ protected SourceSection findSourceLocation(PythonContext context, Object value)
|
437 | 438 | @Override
|
438 | 439 | protected String toString(PythonContext context, Object value) {
|
439 | 440 | 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 | + } |
443 | 467 | }
|
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(); |
450 | 471 | }
|
451 | 472 |
|
452 | 473 | public static TruffleLogger getLogger() {
|
|
0 commit comments