Skip to content

Commit 81a26c7

Browse files
committed
Make inspecting and printing non-python numbers work
Truffle debugger uses inspection facilities provided by the language that constructed given object. But primitive types are an exception and their inspection is always done using the primary language's facilities. Therefore even though we never expose some numeric types such as float, the debugger can still request `PythonLanguage` to inspect them when processing foreign objects that contain them (for example a Java `float[]` array). Add basic inspection facilities for those types.
1 parent fe55db2 commit 81a26c7

File tree

2 files changed

+61
-3
lines changed

2 files changed

+61
-3
lines changed

graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/debug/PythonDebugTest.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464

6565
import com.oracle.graal.python.test.PythonTests;
6666
import com.oracle.truffle.api.debug.Breakpoint;
67+
import com.oracle.truffle.api.debug.DebugScope;
6768
import com.oracle.truffle.api.debug.DebugStackFrame;
6869
import com.oracle.truffle.api.debug.DebugValue;
6970
import com.oracle.truffle.api.debug.DebuggerSession;
@@ -404,6 +405,51 @@ public void testGettersSetters() throws Throwable {
404405
}
405406
}
406407

408+
@Test
409+
public void testInspectJavaArray() throws Throwable {
410+
final Source source = Source.newBuilder("python", "" +
411+
"import java\n" +
412+
"a_int = java.type('int[]')(3)\n" +
413+
"a_long = java.type('long[]')(3)\n" +
414+
"a_short = java.type('short[]')(3)\n" +
415+
"a_byte = java.type('byte[]')(3)\n" +
416+
"a_float = java.type('float[]')(3)\n" +
417+
"a_double = java.type('double[]')(3)\n" +
418+
"a_char = java.type('char[]')(3)\n" +
419+
"print()\n" +
420+
"\n", "testInspectJavaArray.py").buildLiteral();
421+
try (DebuggerSession session = tester.startSession()) {
422+
session.install(Breakpoint.newBuilder(DebuggerTester.getSourceImpl(source)).lineIs(9).build());
423+
tester.startEval(source);
424+
expectSuspended((SuspendedEvent event) -> {
425+
DebugScope globalScope = session.getTopScope("python");
426+
DebugValue intValue = globalScope.getDeclaredValue("a_int").getArray().get(0);
427+
// It's up to Truffle to decide which language it uses for inspection of primitives,
428+
// we should be fine as long as this doesn't throw an exception
429+
intValue.getMetaObject();
430+
assertEquals("0", intValue.as(String.class));
431+
DebugValue longValue = globalScope.getDeclaredValue("a_long").getArray().get(0);
432+
longValue.getMetaObject();
433+
assertEquals("0", longValue.as(String.class));
434+
DebugValue shortValue = globalScope.getDeclaredValue("a_short").getArray().get(0);
435+
shortValue.getMetaObject();
436+
assertEquals("0", shortValue.as(String.class));
437+
DebugValue byteValue = globalScope.getDeclaredValue("a_byte").getArray().get(0);
438+
byteValue.getMetaObject();
439+
assertEquals("0", byteValue.as(String.class));
440+
DebugValue floatValue = globalScope.getDeclaredValue("a_float").getArray().get(0);
441+
floatValue.getMetaObject();
442+
assertEquals("0.0", floatValue.as(String.class));
443+
DebugValue doubleValue = globalScope.getDeclaredValue("a_double").getArray().get(0);
444+
doubleValue.getMetaObject();
445+
assertEquals("0.0", doubleValue.as(String.class));
446+
DebugValue charValue = globalScope.getDeclaredValue("a_char").getArray().get(0);
447+
charValue.getMetaObject();
448+
assertEquals("\0", charValue.as(String.class));
449+
});
450+
}
451+
}
452+
407453
@Test
408454
public void testSourceFileURI() throws Throwable {
409455
if (System.getProperty("os.name").toLowerCase().contains("mac")) {

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
import java.util.function.Supplier;
3333
import java.util.logging.Level;
3434

35+
import org.graalvm.options.OptionDescriptors;
36+
import org.graalvm.options.OptionValues;
37+
3538
import com.oracle.graal.python.builtins.Python3Core;
3639
import com.oracle.graal.python.builtins.objects.PEllipsis;
3740
import com.oracle.graal.python.builtins.objects.PNone;
@@ -94,9 +97,6 @@
9497
import com.oracle.truffle.api.source.Source.SourceBuilder;
9598
import com.oracle.truffle.api.source.SourceSection;
9699

97-
import org.graalvm.options.OptionDescriptors;
98-
import org.graalvm.options.OptionValues;
99-
100100
@TruffleLanguage.Registration(id = PythonLanguage.ID, //
101101
name = PythonLanguage.NAME, //
102102
version = PythonLanguage.VERSION, //
@@ -334,6 +334,10 @@ protected boolean isObjectOfLanguage(Object object) {
334334
return object instanceof PythonAbstractObject;
335335
}
336336

337+
private boolean isForeignPrimitive(Object value) {
338+
return value instanceof Float || value instanceof Short || value instanceof Character || value instanceof Byte;
339+
}
340+
337341
@Override
338342
protected Object findMetaObject(PythonContext context, Object value) {
339343
if (value != null) {
@@ -342,6 +346,9 @@ protected Object findMetaObject(PythonContext context, Object value) {
342346
} else if (PGuards.isNativeObject(value)) {
343347
// TODO(fa): we could also use 'GetClassNode.getItSlowPath(value)' here
344348
return null;
349+
} else if (isForeignPrimitive(value)) {
350+
// these only appear when inspecting foreign data structures
351+
return null;
345352
} else if (value instanceof PythonAbstractObject ||
346353
value instanceof Number ||
347354
value instanceof String ||
@@ -454,6 +461,11 @@ protected SourceSection findSourceLocation(PythonContext context, Object value)
454461

455462
@Override
456463
protected String toString(PythonContext context, Object value) {
464+
if (isForeignPrimitive(value)) {
465+
// these only appear when inspecting foreign data structures, so they shouldn't get
466+
// processed by python code
467+
return value.toString();
468+
}
457469
if (PythonOptions.getFlag(context, PythonOptions.UseReprForPrintString)) {
458470
final PythonModule builtins = context.getBuiltins();
459471
if (builtins != null) {

0 commit comments

Comments
 (0)