Skip to content

Commit e174e67

Browse files
committed
implement hasSourceLocation and getSourceLocation
1 parent 033adee commit e174e67

File tree

7 files changed

+114
-36
lines changed

7 files changed

+114
-36
lines changed

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

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,14 @@
3939
import com.oracle.graal.python.builtins.objects.PNone;
4040
import com.oracle.graal.python.builtins.objects.PNotImplemented;
4141
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
42-
import com.oracle.graal.python.builtins.objects.code.PCode;
4342
import com.oracle.graal.python.builtins.objects.dict.PDict;
4443
import com.oracle.graal.python.builtins.objects.function.PArguments;
45-
import com.oracle.graal.python.builtins.objects.function.PFunction;
46-
import com.oracle.graal.python.builtins.objects.list.PList;
47-
import com.oracle.graal.python.builtins.objects.method.PMethod;
4844
import com.oracle.graal.python.builtins.objects.object.PythonObject;
49-
import com.oracle.graal.python.builtins.objects.type.PythonManagedClass;
5045
import com.oracle.graal.python.nodes.BuiltinNames;
5146
import com.oracle.graal.python.nodes.NodeFactory;
52-
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromDynamicObjectNode;
5347
import com.oracle.graal.python.nodes.control.TopLevelExceptionHandler;
5448
import com.oracle.graal.python.nodes.expression.ExpressionNode;
5549
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
56-
import com.oracle.graal.python.nodes.literal.ListLiteralNode;
5750
import com.oracle.graal.python.parser.PythonParserImpl;
5851
import com.oracle.graal.python.runtime.PythonContext;
5952
import com.oracle.graal.python.runtime.PythonCore;
@@ -88,7 +81,6 @@
8881
import com.oracle.truffle.api.nodes.RootNode;
8982
import com.oracle.truffle.api.source.Source;
9083
import com.oracle.truffle.api.source.Source.SourceBuilder;
91-
import com.oracle.truffle.api.source.SourceSection;
9284

9385
import org.graalvm.options.OptionDescriptors;
9486
import org.graalvm.options.OptionValues;
@@ -428,34 +420,6 @@ protected Iterable<Scope> findTopScopes(PythonContext context) {
428420
return scopes;
429421
}
430422

431-
@Override
432-
@TruffleBoundary
433-
protected SourceSection findSourceLocation(PythonContext context, Object value) {
434-
if (value instanceof PFunction) {
435-
PFunction callable = (PFunction) value;
436-
return callable.getCallTarget().getRootNode().getSourceSection();
437-
} else if (value instanceof PMethod && ((PMethod) value).getFunction() instanceof PFunction) {
438-
PFunction callable = (PFunction) ((PMethod) value).getFunction();
439-
return callable.getCallTarget().getRootNode().getSourceSection();
440-
} else if (value instanceof PCode) {
441-
return ((PCode) value).getRootNode().getSourceSection();
442-
} else if (value instanceof PythonManagedClass) {
443-
for (String k : ((PythonManagedClass) value).getAttributeNames()) {
444-
Object attrValue = ReadAttributeFromDynamicObjectNode.getUncached().execute(((PythonManagedClass) value).getStorage(), k);
445-
SourceSection attrSourceLocation = findSourceLocation(context, attrValue);
446-
if (attrSourceLocation != null) {
447-
return attrSourceLocation;
448-
}
449-
}
450-
} else if (value instanceof PList) {
451-
ListLiteralNode node = ((PList) value).getOrigin();
452-
if (node != null) {
453-
return node.getSourceSection();
454-
}
455-
}
456-
return null;
457-
}
458-
459423
@TruffleBoundary
460424
public static TruffleLogger getLogger() {
461425
return TruffleLogger.getLogger(ID);

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@
147147
import com.oracle.truffle.api.nodes.Node;
148148
import com.oracle.truffle.api.profiles.BranchProfile;
149149
import com.oracle.truffle.api.profiles.ConditionProfile;
150+
import com.oracle.truffle.api.source.SourceSection;
150151

151152
@ExportLibrary(InteropLibrary.class)
152153
@ExportLibrary(PythonObjectLibrary.class)
@@ -1828,4 +1829,16 @@ public boolean hasMetaObject() {
18281829
public Object getMetaObject(@Shared("getClassThis") @Cached GetClassNode getClass) {
18291830
return getClass.execute(this);
18301831
}
1832+
1833+
@ExportMessage
1834+
@SuppressWarnings("static-method")
1835+
public SourceSection getSourceLocation() {
1836+
return null;
1837+
}
1838+
1839+
@ExportMessage
1840+
@SuppressWarnings("static-method")
1841+
public boolean hasSourceLocation() {
1842+
return false;
1843+
}
18311844
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/PCode.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
import com.oracle.truffle.api.CompilerDirectives;
6565
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
6666
import com.oracle.truffle.api.RootCallTarget;
67+
import com.oracle.truffle.api.library.ExportMessage;
6768
import com.oracle.truffle.api.nodes.NodeUtil;
6869
import com.oracle.truffle.api.nodes.RootNode;
6970
import com.oracle.truffle.api.source.SourceSection;
@@ -443,4 +444,16 @@ public Signature getSignature() {
443444
public RootCallTarget getRootCallTarget() {
444445
return callTarget;
445446
}
447+
448+
@Override
449+
@ExportMessage
450+
public SourceSection getSourceLocation() {
451+
return getRootNode().getSourceSection();
452+
}
453+
454+
@Override
455+
@ExportMessage
456+
public boolean hasSourceLocation() {
457+
return true;
458+
}
446459
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PFunction.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,16 @@ public String getSourceCode() {
203203
public boolean isCallable() {
204204
return true;
205205
}
206+
207+
@Override
208+
@ExportMessage
209+
public SourceSection getSourceLocation() {
210+
return getCallTarget().getRootNode().getSourceSection();
211+
}
212+
213+
@Override
214+
@ExportMessage
215+
public boolean hasSourceLocation() {
216+
return true;
217+
}
206218
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/list/PList.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,10 @@
3131
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
3232
import com.oracle.graal.python.runtime.sequence.storage.SequenceStoreException;
3333
import com.oracle.truffle.api.CompilerDirectives;
34+
import com.oracle.truffle.api.library.ExportMessage;
35+
import com.oracle.truffle.api.library.ExportMessage.Ignore;
3436
import com.oracle.truffle.api.nodes.UnexpectedResultException;
37+
import com.oracle.truffle.api.source.SourceSection;
3538

3639
public final class PList extends PMutableSequence {
3740
private final ListLiteralNode origin;
@@ -94,6 +97,7 @@ public final void insert(int index, Object value) {
9497
}
9598
}
9699

100+
@Ignore
97101
@Override
98102
public final boolean equals(Object other) {
99103
if (!(other instanceof PList)) {
@@ -130,4 +134,17 @@ public static PList expect(Object value) throws UnexpectedResultException {
130134
}
131135
throw new UnexpectedResultException(value);
132136
}
137+
138+
@Override
139+
@ExportMessage
140+
public SourceSection getSourceLocation() {
141+
ListLiteralNode node = getOrigin();
142+
return node != null ? node.getSourceSection() : null;
143+
}
144+
145+
@Override
146+
@ExportMessage
147+
public boolean hasSourceLocation() {
148+
return getOrigin() != null && getOrigin().getSourceSection() != null;
149+
}
133150
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/method/PMethod.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,12 @@
2929
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
3030
import com.oracle.graal.python.builtins.objects.type.LazyPythonClass;
3131
import com.oracle.truffle.api.CompilerAsserts;
32+
import com.oracle.truffle.api.interop.InteropLibrary;
33+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
34+
import com.oracle.truffle.api.library.CachedLibrary;
3235
import com.oracle.truffle.api.library.ExportLibrary;
3336
import com.oracle.truffle.api.library.ExportMessage;
37+
import com.oracle.truffle.api.source.SourceSection;
3438

3539
@ExportLibrary(PythonObjectLibrary.class)
3640
public final class PMethod extends PythonBuiltinObject {
@@ -63,4 +67,14 @@ public String toString() {
6367
public boolean isCallable() {
6468
return true;
6569
}
70+
71+
@ExportMessage
72+
protected SourceSection getSourceLocation(@CachedLibrary(limit = "1") InteropLibrary lib) throws UnsupportedMessageException {
73+
return lib.getSourceLocation(function);
74+
}
75+
76+
@ExportMessage
77+
protected boolean hasSourceLocation(@CachedLibrary(limit = "1") InteropLibrary lib) {
78+
return lib.hasSourceLocation(function);
79+
}
6680
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/type/PythonManagedClass.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,20 @@
4040
import com.oracle.graal.python.builtins.objects.type.TypeNodes.ComputeMroNode;
4141
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetSubclassesNode;
4242
import com.oracle.graal.python.nodes.PGuards;
43+
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromDynamicObjectNode;
4344
import com.oracle.graal.python.runtime.sequence.storage.MroSequenceStorage;
4445
import com.oracle.truffle.api.Assumption;
4546
import com.oracle.truffle.api.CompilerAsserts;
4647
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
4748
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
49+
import com.oracle.truffle.api.dsl.Cached;
50+
import com.oracle.truffle.api.dsl.Cached.Shared;
51+
import com.oracle.truffle.api.interop.InteropLibrary;
52+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
53+
import com.oracle.truffle.api.library.ExportMessage;
54+
import com.oracle.truffle.api.object.DynamicObject;
4855
import com.oracle.truffle.api.object.Shape;
56+
import com.oracle.truffle.api.source.SourceSection;
4957

5058
public abstract class PythonManagedClass extends PythonObject implements PythonAbstractClass {
5159

@@ -238,4 +246,41 @@ public boolean needsNativeAllocation() {
238246
return needsNativeAllocation;
239247
}
240248

249+
/*
250+
* N.b.: (tfel): This method is used to cache the source section of the first defined attribute
251+
* that has a source section. This isn't precisely the classes definition location, but it is
252+
* close. We can safely cache this regardless of any later shape changes or redefinitions,
253+
* because this is best-effort only anyway. If it is called early, it is very likely we're
254+
* getting some location near the actual definition. If it is called late, and potentially after
255+
* some monkey-patching, we'll get some other source location.
256+
*/
257+
protected static SourceSection findSourceSection(PythonManagedClass self) {
258+
DynamicObject storage = self.getStorage();
259+
for (Object key : storage.getShape().getKeys()) {
260+
if (key instanceof String) {
261+
Object value = ReadAttributeFromDynamicObjectNode.getUncached().execute(storage, key);
262+
InteropLibrary uncached = InteropLibrary.getFactory().getUncached();
263+
if (uncached.hasSourceLocation(value)) {
264+
try {
265+
return uncached.getSourceLocation(value);
266+
} catch (UnsupportedMessageException e) {
267+
// should not happen due to hasSourceLocation check
268+
}
269+
}
270+
}
271+
}
272+
return null;
273+
}
274+
275+
@ExportMessage
276+
protected SourceSection getSourceLocation(
277+
@Shared("src") @Cached(value = "findSourceSection(this)", allowUncached = true) SourceSection section) {
278+
return section;
279+
}
280+
281+
@ExportMessage
282+
protected boolean hasSourceLocation(
283+
@Shared("src") @Cached(value = "findSourceSection(this)", allowUncached = true) SourceSection section) {
284+
return section != null;
285+
}
241286
}

0 commit comments

Comments
 (0)