Skip to content

Commit 4691b84

Browse files
committed
[GR-9228] Support TryBlockTag
1 parent 9998dee commit 4691b84

File tree

2 files changed

+136
-5
lines changed

2 files changed

+136
-5
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
import com.oracle.truffle.api.source.Source;
7171

7272
@TruffleLanguage.Registration(id = PythonLanguage.ID, name = PythonLanguage.NAME, version = PythonLanguage.VERSION, mimeType = PythonLanguage.MIME_TYPE, interactive = true, internal = false)
73-
@ProvidedTags({StandardTags.CallTag.class, StandardTags.StatementTag.class, StandardTags.RootTag.class, DebuggerTags.AlwaysHalt.class})
73+
@ProvidedTags({StandardTags.CallTag.class, StandardTags.StatementTag.class, StandardTags.RootTag.class, StandardTags.TryBlockTag.class, DebuggerTags.AlwaysHalt.class})
7474
public final class PythonLanguage extends TruffleLanguage<PythonContext> {
7575

7676
public static final String ID = "python";

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/statement/TryExceptNode.java

Lines changed: 135 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,41 @@
2727

2828
import static com.oracle.graal.python.runtime.PythonOptions.CatchAllExceptions;
2929

30+
import java.util.ArrayList;
31+
import java.util.List;
32+
3033
import com.oracle.graal.python.builtins.objects.PNone;
3134
import com.oracle.graal.python.builtins.objects.exception.PBaseException;
35+
import com.oracle.graal.python.builtins.objects.module.PythonModule;
3236
import com.oracle.graal.python.nodes.PNode;
37+
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
38+
import com.oracle.graal.python.nodes.frame.ReadGlobalOrBuiltinNode;
39+
import com.oracle.graal.python.nodes.literal.TupleLiteralNode;
3340
import com.oracle.graal.python.runtime.PythonOptions;
3441
import com.oracle.graal.python.runtime.exception.ExceptionHandledException;
3542
import com.oracle.graal.python.runtime.exception.PException;
3643
import com.oracle.graal.python.runtime.exception.PythonErrorType;
37-
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
38-
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
3944
import com.oracle.truffle.api.CompilerDirectives;
45+
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
46+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
4047
import com.oracle.truffle.api.frame.VirtualFrame;
48+
import com.oracle.truffle.api.instrumentation.StandardTags;
49+
import com.oracle.truffle.api.instrumentation.Tag;
50+
import com.oracle.truffle.api.interop.ArityException;
51+
import com.oracle.truffle.api.interop.CanResolve;
52+
import com.oracle.truffle.api.interop.ForeignAccess;
53+
import com.oracle.truffle.api.interop.MessageResolution;
54+
import com.oracle.truffle.api.interop.Resolve;
55+
import com.oracle.truffle.api.interop.TruffleObject;
56+
import com.oracle.truffle.api.interop.UnknownIdentifierException;
4157
import com.oracle.truffle.api.nodes.ControlFlowException;
4258
import com.oracle.truffle.api.nodes.ExplodeLoop;
59+
import com.oracle.truffle.api.nodes.Node;
4360

44-
public class TryExceptNode extends StatementNode {
61+
public class TryExceptNode extends StatementNode implements TruffleObject {
4562

4663
@Child private PNode body;
47-
@Children final ExceptNode[] exceptNodes;
64+
@Children private final ExceptNode[] exceptNodes;
4865
@Child private PNode orelse;
4966

5067
@CompilationFinal boolean seenException;
@@ -125,4 +142,118 @@ public ExceptNode[] getExceptNodes() {
125142
public PNode getOrelse() {
126143
return orelse;
127144
}
145+
146+
@Override
147+
public boolean hasTag(Class<? extends Tag> tag) {
148+
return super.hasTag(tag) || StandardTags.TryBlockTag.class == tag;
149+
}
150+
151+
public Object getNodeObject() {
152+
return this;
153+
}
154+
155+
public ForeignAccess getForeignAccess() {
156+
return ExceptBlockMRForeign.ACCESS;
157+
}
158+
159+
@MessageResolution(receiverType = TryExceptNode.class)
160+
static class ExceptBlockMR {
161+
@Resolve(message = "HAS_KEYS")
162+
abstract static class HasKeysNode extends Node {
163+
Object access(@SuppressWarnings("unused") TryExceptNode object) {
164+
return true;
165+
}
166+
}
167+
168+
@Resolve(message = "KEYS")
169+
abstract static class KeysNode extends Node {
170+
Object access(TryExceptNode object) {
171+
return object.getContext().getEnv().asGuestValue(new String[]{StandardTags.TryBlockTag.CATCHES});
172+
}
173+
}
174+
175+
@Resolve(message = "READ")
176+
abstract static class ReadNode extends Node {
177+
Object access(TryExceptNode object, String name) {
178+
if (name.equals(StandardTags.TryBlockTag.CATCHES)) {
179+
ExceptNode[] exceptNodes = object.getExceptNodes();
180+
List<String> literalCatches = new ArrayList<>();
181+
for (ExceptNode node : exceptNodes) {
182+
PNode exceptType = node.getExceptType();
183+
if (exceptType instanceof ReadGlobalOrBuiltinNode) {
184+
literalCatches.add(((ReadGlobalOrBuiltinNode) exceptType).getAttributeId());
185+
} else if (exceptType instanceof TupleLiteralNode) {
186+
for (PNode tupleValue : ((TupleLiteralNode) exceptType).getValues()) {
187+
if (tupleValue instanceof ReadGlobalOrBuiltinNode) {
188+
literalCatches.add(((ReadGlobalOrBuiltinNode) tupleValue).getAttributeId());
189+
}
190+
}
191+
}
192+
}
193+
return new CatchesFunction(object.getContext().getBuiltins(), literalCatches.toArray(new String[0]));
194+
} else {
195+
throw UnknownIdentifierException.raise(name);
196+
}
197+
}
198+
}
199+
200+
@CanResolve
201+
abstract static class CheckFunction extends Node {
202+
protected static boolean test(TruffleObject receiver) {
203+
return receiver instanceof TryExceptNode;
204+
}
205+
}
206+
207+
protected static class CatchesFunction implements TruffleObject {
208+
private final PythonModule builtins;
209+
@CompilationFinal(dimensions = 1) private final String[] attributes;
210+
private final ReadAttributeFromObjectNode getAttribute = ReadAttributeFromObjectNode.create();
211+
212+
CatchesFunction(PythonModule builtins, String[] array) {
213+
this.builtins = builtins;
214+
this.attributes = array;
215+
}
216+
217+
boolean catches(Object exception) {
218+
for (String name : attributes) {
219+
Object execute = getAttribute.execute(builtins, name);
220+
if (execute == exception) {
221+
return true;
222+
}
223+
}
224+
return false;
225+
}
226+
227+
public ForeignAccess getForeignAccess() {
228+
return ExceptListMRForeign.ACCESS;
229+
}
230+
231+
@MessageResolution(receiverType = CatchesFunction.class)
232+
static class ExceptListMR {
233+
@Resolve(message = "IS_EXECUTABLE")
234+
abstract static class IsExecutableNode extends Node {
235+
Object access(@SuppressWarnings("unused") CatchesFunction object) {
236+
return true;
237+
}
238+
}
239+
240+
@Resolve(message = "EXECUTE")
241+
abstract static class ExecuteNode extends Node {
242+
Object access(CatchesFunction object, Object[] arguments) {
243+
if (arguments.length != 1) {
244+
throw ArityException.raise(1, arguments.length);
245+
}
246+
return object.catches(arguments[0]);
247+
}
248+
}
249+
250+
@CanResolve
251+
abstract static class CheckFunction extends Node {
252+
protected static boolean test(TruffleObject receiver) {
253+
return receiver instanceof TryExceptNode;
254+
}
255+
}
256+
}
257+
}
258+
}
128259
}

0 commit comments

Comments
 (0)