Skip to content

Commit 4801720

Browse files
committed
add the try tag to the body of the try-catch node
1 parent 4691b84 commit 4801720

File tree

2 files changed

+111
-35
lines changed

2 files changed

+111
-35
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PNode.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
*/
2626
package com.oracle.graal.python.nodes;
2727

28+
import com.oracle.graal.python.nodes.statement.TryExceptNode;
2829
import com.oracle.graal.python.nodes.truffle.PythonTypes;
2930
import com.oracle.graal.python.runtime.PythonOptions;
3031
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
@@ -46,6 +47,7 @@ public abstract class PNode extends PBaseNode implements InstrumentableNode {
4647
@CompilationFinal private SourceSection sourceSection;
4748
@CompilationFinal private boolean isStmt = false;
4849
@CompilationFinal private boolean isRoot = false;
50+
@CompilationFinal private boolean isTryBlock = false;
4951

5052
public NodeFactory getNodeFactory() {
5153
return getCore().getLanguage().getNodeFactory();
@@ -115,7 +117,7 @@ public void assignSourceSection(SourceSection source) {
115117
}
116118

117119
public boolean hasTag(Class<? extends Tag> tag) {
118-
return (isStmt && tag == StandardTags.StatementTag.class) || (isRoot && tag == StandardTags.RootTag.class);
120+
return (isStmt && tag == StandardTags.StatementTag.class) || (isRoot && tag == StandardTags.RootTag.class) || (isTryBlock && tag == StandardTags.TryBlockTag.class);
119121
}
120122

121123
public WrapperNode createWrapper(ProbeNode probeNode) {
@@ -141,4 +143,24 @@ public void markAsRoot() {
141143
public boolean isRoot() {
142144
return isRoot;
143145
}
146+
147+
public void markAsTryBlock() {
148+
isTryBlock = true;
149+
}
150+
151+
public boolean isTryBlock() {
152+
return isTryBlock;
153+
}
154+
155+
public Object getNodeObject() {
156+
if (isTryBlock) {
157+
if (this.getParent() instanceof TryExceptNode) {
158+
return this.getParent();
159+
} else if (this.getParent() instanceof PNodeWrapper) {
160+
assert this.getParent().getParent() instanceof TryExceptNode;
161+
return this.getParent().getParent();
162+
}
163+
}
164+
return null;
165+
}
144166
}

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

Lines changed: 88 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -28,28 +28,34 @@
2828
import static com.oracle.graal.python.runtime.PythonOptions.CatchAllExceptions;
2929

3030
import java.util.ArrayList;
31-
import java.util.List;
3231

3332
import com.oracle.graal.python.builtins.objects.PNone;
3433
import com.oracle.graal.python.builtins.objects.exception.PBaseException;
34+
import com.oracle.graal.python.builtins.objects.function.PArguments;
35+
import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
3536
import com.oracle.graal.python.builtins.objects.module.PythonModule;
37+
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
38+
import com.oracle.graal.python.nodes.BuiltinNames;
3639
import com.oracle.graal.python.nodes.PNode;
37-
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode;
40+
import com.oracle.graal.python.nodes.attributes.GetAttributeNode;
3841
import com.oracle.graal.python.nodes.frame.ReadGlobalOrBuiltinNode;
3942
import com.oracle.graal.python.nodes.literal.TupleLiteralNode;
43+
import com.oracle.graal.python.nodes.statement.TryExceptNode.ExceptBlockMR.CatchesFunction;
44+
import com.oracle.graal.python.nodes.statement.TryExceptNode.ExceptBlockMR.CatchesFunction.ExceptListMR.ExecuteNode;
4045
import com.oracle.graal.python.runtime.PythonOptions;
4146
import com.oracle.graal.python.runtime.exception.ExceptionHandledException;
4247
import com.oracle.graal.python.runtime.exception.PException;
4348
import com.oracle.graal.python.runtime.exception.PythonErrorType;
4449
import com.oracle.truffle.api.CompilerDirectives;
4550
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
4651
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
52+
import com.oracle.truffle.api.RootCallTarget;
4753
import com.oracle.truffle.api.frame.VirtualFrame;
4854
import com.oracle.truffle.api.instrumentation.StandardTags;
49-
import com.oracle.truffle.api.instrumentation.Tag;
5055
import com.oracle.truffle.api.interop.ArityException;
5156
import com.oracle.truffle.api.interop.CanResolve;
5257
import com.oracle.truffle.api.interop.ForeignAccess;
58+
import com.oracle.truffle.api.interop.KeyInfo;
5359
import com.oracle.truffle.api.interop.MessageResolution;
5460
import com.oracle.truffle.api.interop.Resolve;
5561
import com.oracle.truffle.api.interop.TruffleObject;
@@ -64,10 +70,13 @@ public class TryExceptNode extends StatementNode implements TruffleObject {
6470
@Children private final ExceptNode[] exceptNodes;
6571
@Child private PNode orelse;
6672

73+
@CompilationFinal CatchesFunction catchesFunction;
74+
6775
@CompilationFinal boolean seenException;
6876

6977
public TryExceptNode(PNode body, ExceptNode[] exceptNodes, PNode orelse) {
7078
this.body = body;
79+
body.markAsTryBlock();
7180
this.exceptNodes = exceptNodes;
7281
this.orelse = orelse;
7382
}
@@ -144,14 +153,6 @@ public PNode getOrelse() {
144153
}
145154

146155
@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-
155156
public ForeignAccess getForeignAccess() {
156157
return ExceptBlockMRForeign.ACCESS;
157158
}
@@ -172,31 +173,79 @@ Object access(TryExceptNode object) {
172173
}
173174
}
174175

176+
@Resolve(message = "KEY_INFO")
177+
abstract static class KeyInfoNode extends Node {
178+
Object access(@SuppressWarnings("unused") TryExceptNode object, String name) {
179+
if (name.equals(StandardTags.TryBlockTag.CATCHES)) {
180+
return KeyInfo.INVOCABLE | KeyInfo.READABLE;
181+
} else {
182+
return KeyInfo.NONE;
183+
}
184+
}
185+
}
186+
175187
@Resolve(message = "READ")
176188
abstract static class ReadNode extends Node {
177-
Object access(TryExceptNode object, String name) {
189+
@Child GetAttributeNode getAttr = GetAttributeNode.create();
190+
191+
CatchesFunction access(TryExceptNode object, String name) {
192+
return doit(object, name, getAttr);
193+
}
194+
195+
static CatchesFunction doit(TryExceptNode object, String name, GetAttributeNode getAttr) {
178196
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());
197+
if (object.catchesFunction == null) {
198+
CompilerDirectives.transferToInterpreterAndInvalidate();
199+
ArrayList<Object> literalCatches = new ArrayList<>();
200+
ExceptNode[] exceptNodes = object.getExceptNodes();
201+
PythonModule builtins = object.getContext().getBuiltins();
202+
203+
for (ExceptNode node : exceptNodes) {
204+
PNode exceptType = node.getExceptType();
205+
if (exceptType instanceof ReadGlobalOrBuiltinNode) {
206+
try {
207+
literalCatches.add(getAttr.execute(builtins, ((ReadGlobalOrBuiltinNode) exceptType).getAttributeId()));
208+
} catch (PException e) {
209+
}
210+
} else if (exceptType instanceof TupleLiteralNode) {
211+
for (PNode tupleValue : ((TupleLiteralNode) exceptType).getValues()) {
212+
if (tupleValue instanceof ReadGlobalOrBuiltinNode) {
213+
try {
214+
literalCatches.add(getAttr.execute(builtins, ((ReadGlobalOrBuiltinNode) tupleValue).getAttributeId()));
215+
} catch (PException e) {
216+
}
217+
}
189218
}
190219
}
191220
}
221+
222+
Object isinstanceFunc = getAttr.execute(builtins, BuiltinNames.ISINSTANCE);
223+
PTuple caughtClasses = object.factory().createTuple(literalCatches.toArray());
224+
225+
if (isinstanceFunc instanceof PBuiltinFunction) {
226+
RootCallTarget callTarget = ((PBuiltinFunction) isinstanceFunc).getCallTarget();
227+
object.catchesFunction = new CatchesFunction(callTarget, caughtClasses);
228+
} else {
229+
throw new IllegalStateException("isinstance was redefined, cannot check exceptions");
230+
}
192231
}
193-
return new CatchesFunction(object.getContext().getBuiltins(), literalCatches.toArray(new String[0]));
232+
return object.catchesFunction;
194233
} else {
195234
throw UnknownIdentifierException.raise(name);
196235
}
197236
}
198237
}
199238

239+
@Resolve(message = "INVOKE")
240+
abstract static class InvokeNode extends Node {
241+
@Child GetAttributeNode getAttr = GetAttributeNode.create();
242+
243+
Object access(TryExceptNode object, String name, Object[] arguments) {
244+
CatchesFunction catchesFunction = ReadNode.doit(object, name, getAttr);
245+
return ExecuteNode.access(catchesFunction, arguments);
246+
}
247+
}
248+
200249
@CanResolve
201250
abstract static class CheckFunction extends Node {
202251
protected static boolean test(TruffleObject receiver) {
@@ -205,20 +254,25 @@ protected static boolean test(TruffleObject receiver) {
205254
}
206255

207256
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();
257+
private final RootCallTarget isInstance;
258+
private final PTuple caughtClasses;
259+
private final Object[] args = PArguments.create(2);
211260

212-
CatchesFunction(PythonModule builtins, String[] array) {
213-
this.builtins = builtins;
214-
this.attributes = array;
261+
CatchesFunction(RootCallTarget callTarget, PTuple caughtClasses) {
262+
this.isInstance = callTarget;
263+
this.caughtClasses = caughtClasses;
215264
}
216265

266+
@ExplodeLoop
217267
boolean catches(Object exception) {
218-
for (String name : attributes) {
219-
Object execute = getAttribute.execute(builtins, name);
220-
if (execute == exception) {
221-
return true;
268+
if (exception instanceof PBaseException) {
269+
PArguments.setArgument(args, 0, exception);
270+
PArguments.setArgument(args, 1, caughtClasses);
271+
try {
272+
if (isInstance.call(args) == Boolean.TRUE) {
273+
return true;
274+
}
275+
} catch (PException e) {
222276
}
223277
}
224278
return false;
@@ -239,7 +293,7 @@ Object access(@SuppressWarnings("unused") CatchesFunction object) {
239293

240294
@Resolve(message = "EXECUTE")
241295
abstract static class ExecuteNode extends Node {
242-
Object access(CatchesFunction object, Object[] arguments) {
296+
static Object access(CatchesFunction object, Object[] arguments) {
243297
if (arguments.length != 1) {
244298
throw ArityException.raise(1, arguments.length);
245299
}

0 commit comments

Comments
 (0)