Skip to content

Commit d8407f4

Browse files
committed
[GR-23265][GR-23230] Fixes for test_traceback and test_frame
PullRequest: graalpython/1155
2 parents d6f58f0 + bef5b4c commit d8407f4

File tree

20 files changed

+223
-42
lines changed

20 files changed

+223
-42
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
*graalpython.lib-python.3.test.test_frame.ClearTest.test_clear_locals
12
*graalpython.lib-python.3.test.test_frame.ClearTest.test_clear_refcycles
23
*graalpython.lib-python.3.test.test_frame.FrameAttrsTest.test_f_lineno_del_segfault
34
*graalpython.lib-python.3.test.test_frame.FrameAttrsTest.test_locals
5+
*graalpython.lib-python.3.test.test_frame.ReprTest.test_repr

graalpython/com.oracle.graal.python.test/src/tests/unittest_tags/test_traceback.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
*graalpython.lib-python.3.test.test_traceback.TestStack.test_extract_stack_limit
2828
*graalpython.lib-python.3.test.test_traceback.TestStack.test_extract_stack_lookup_lines
2929
*graalpython.lib-python.3.test.test_traceback.TestStack.test_extract_stackup_deferred_lookup_lines
30+
*graalpython.lib-python.3.test.test_traceback.TestStack.test_format_locals
3031
*graalpython.lib-python.3.test.test_traceback.TestStack.test_format_smoke
3132
*graalpython.lib-python.3.test.test_traceback.TestStack.test_from_list
3233
*graalpython.lib-python.3.test.test_traceback.TestStack.test_from_list_edited_stack
@@ -51,9 +52,11 @@
5152
*graalpython.lib-python.3.test.test_traceback.TracebackCases.test_format_exception_only_bad__str__
5253
*graalpython.lib-python.3.test.test_traceback.TracebackCases.test_nocaret
5354
*graalpython.lib-python.3.test.test_traceback.TracebackCases.test_print_exception
55+
*graalpython.lib-python.3.test.test_traceback.TracebackCases.test_print_traceback_at_exit
5456
*graalpython.lib-python.3.test.test_traceback.TracebackFormatTests.test_format_stack
5557
*graalpython.lib-python.3.test.test_traceback.TracebackFormatTests.test_print_stack
5658
*graalpython.lib-python.3.test.test_traceback.TracebackFormatTests.test_recursive_traceback_cpython_internal
59+
*graalpython.lib-python.3.test.test_traceback.TracebackFormatTests.test_recursive_traceback_python
5760
*graalpython.lib-python.3.test.test_traceback.TracebackFormatTests.test_stack_format
5861
*graalpython.lib-python.3.test.test_traceback.TracebackFormatTests.test_traceback_format
5962
*graalpython.lib-python.3.test.test_traceback.TracebackFormatTests.test_traceback_format_with_cleared_frames

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/GraalPythonModuleBuiltins.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -389,22 +389,22 @@ public synchronized PFunction convertToBuiltin(PFunction func) {
389389
*/
390390
Signature signature = func.getSignature();
391391
PFunction builtinFunc;
392+
FunctionRootNode functionRootNode = (FunctionRootNode) func.getFunctionRootNode();
392393
if (signature.getParameterIds().length > 0 && signature.getParameterIds()[0].equals("self")) {
393394
/*
394395
* If the first parameter is called self, we assume the function does explicitly
395396
* declare the module argument
396397
*/
397398
builtinFunc = func;
399+
functionRootNode.setPythonInternal(true);
398400
} else {
399401
/*
400402
* Otherwise, we create a new function with a signature that requires one extra
401403
* argument in front. We actually modify the function's AST here, so the original
402404
* PFunction cannot be used anymore (its signature won't agree with it's indexed
403405
* parameter reads).
404406
*/
405-
FunctionRootNode functionRootNode = (FunctionRootNode) func.getFunctionRootNode();
406-
assert !functionRootNode.isRewritten() : "a function cannot be annotated as builtin twice";
407-
407+
assert !functionRootNode.isPythonInternal() : "a function cannot be rewritten as builtin twice";
408408
functionRootNode = functionRootNode.rewriteWithNewSignature(signature.createWithSelf(), new NodeVisitor() {
409409

410410
public boolean visit(Node node) {
@@ -428,6 +428,17 @@ public boolean visit(Node node) {
428428
}
429429
}
430430

431+
@Builtin(name = "builtin_method", minNumOfPositionalArgs = 1)
432+
@GenerateNodeFactory
433+
public abstract static class BuiltinMethodNode extends PythonUnaryBuiltinNode {
434+
@Specialization
435+
public Object doIt(PFunction func) {
436+
FunctionRootNode functionRootNode = (FunctionRootNode) func.getFunctionRootNode();
437+
functionRootNode.setPythonInternal(true);
438+
return func;
439+
}
440+
}
441+
431442
@Builtin(name = "get_toolchain_path", minNumOfPositionalArgs = 1)
432443
@TypeSystemReference(PythonArithmeticTypes.class)
433444
@GenerateNodeFactory

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/frame/FrameBuiltins.java

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
*/
2626
package com.oracle.graal.python.builtins.objects.frame;
2727

28+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__REPR__;
29+
2830
import java.util.List;
2931

3032
import com.oracle.graal.python.builtins.Builtin;
@@ -33,20 +35,23 @@
3335
import com.oracle.graal.python.builtins.PythonBuiltins;
3436
import com.oracle.graal.python.builtins.objects.PNone;
3537
import com.oracle.graal.python.builtins.objects.code.CodeNodes;
38+
import com.oracle.graal.python.builtins.objects.code.PCode;
3639
import com.oracle.graal.python.builtins.objects.frame.PFrame.Reference;
3740
import com.oracle.graal.python.builtins.objects.function.PArguments;
3841
import com.oracle.graal.python.builtins.objects.module.PythonModule;
3942
import com.oracle.graal.python.builtins.objects.object.ObjectBuiltins.DictNode;
4043
import com.oracle.graal.python.builtins.objects.object.ObjectBuiltinsFactory.DictNodeFactory;
4144
import com.oracle.graal.python.builtins.objects.object.PythonObject;
4245
import com.oracle.graal.python.nodes.PRootNode;
46+
import com.oracle.graal.python.nodes.argument.ReadArgumentNode;
4347
import com.oracle.graal.python.nodes.frame.MaterializeFrameNode;
4448
import com.oracle.graal.python.nodes.frame.ReadCallerFrameNode;
4549
import com.oracle.graal.python.nodes.frame.ReadLocalsNode;
4650
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
4751
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
4852
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
4953
import com.oracle.truffle.api.CompilerDirectives;
54+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
5055
import com.oracle.truffle.api.RootCallTarget;
5156
import com.oracle.truffle.api.dsl.Cached;
5257
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
@@ -64,6 +69,25 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
6469
return FrameBuiltinsFactory.getFactories();
6570
}
6671

72+
@Builtin(name = __REPR__, minNumOfPositionalArgs = 1)
73+
@GenerateNodeFactory
74+
public abstract static class ReprNode extends PythonUnaryBuiltinNode {
75+
@Specialization
76+
String repr(VirtualFrame frame, PFrame self,
77+
@Cached GetCodeNode getCodeNode,
78+
@Cached GetLinenoNode getLinenoNode) {
79+
PCode code = getCodeNode.executeObject(frame, self);
80+
int lineno = getLinenoNode.executeInt(frame, self);
81+
return getFormat(self, code, lineno);
82+
}
83+
84+
@TruffleBoundary
85+
private static String getFormat(PFrame self, PCode code, int lineno) {
86+
return String.format("<frame at 0x%x, file '%s', line %d, code %s>",
87+
self.hashCode(), code.getFilename(), lineno, code.getName());
88+
}
89+
}
90+
6791
@Builtin(name = "f_globals", minNumOfPositionalArgs = 1, isGetter = true)
6892
@GenerateNodeFactory
6993
public abstract static class GetGlobalsNode extends PythonBuiltinNode {
@@ -102,10 +126,26 @@ Object get(VirtualFrame frame, @SuppressWarnings("unused") PFrame self) {
102126
@Builtin(name = "f_lineno", minNumOfPositionalArgs = 1, isGetter = true)
103127
@GenerateNodeFactory
104128
public abstract static class GetLinenoNode extends PythonBuiltinNode {
129+
public abstract int executeInt(VirtualFrame frame, PFrame self);
130+
105131
@Specialization
106-
int get(PFrame self) {
132+
int get(VirtualFrame frame, PFrame self,
133+
@Cached ConditionProfile isCurrentFrameProfile,
134+
@Cached MaterializeFrameNode materializeNode) {
135+
// Special case because this builtin can be called without going through an invoke node:
136+
// we need to sync the location of the frame if and only if 'self' represents the
137+
// current frame. If 'self' represents another frame on the stack, the location is
138+
// already set
139+
if (isCurrentFrameProfile.profile(PArguments.getCurrentFrameInfo(frame) == self.getRef())) {
140+
PFrame pyFrame = materializeNode.execute(frame, this, false, false);
141+
assert pyFrame == self;
142+
}
107143
return self.getLine();
108144
}
145+
146+
public static GetLinenoNode create() {
147+
return FrameBuiltinsFactory.GetLinenoNodeFactory.create(new ReadArgumentNode[0]);
148+
}
109149
}
110150

111151
@Builtin(name = "f_lasti", minNumOfPositionalArgs = 1, isGetter = true)
@@ -131,8 +171,10 @@ Object get(@SuppressWarnings("unused") PFrame self) {
131171
@Builtin(name = "f_code", minNumOfPositionalArgs = 1, isGetter = true)
132172
@GenerateNodeFactory
133173
public abstract static class GetCodeNode extends PythonBuiltinNode {
174+
public abstract PCode executeObject(VirtualFrame frame, PFrame self);
175+
134176
@Specialization
135-
Object get(VirtualFrame frame, PFrame self,
177+
PCode get(VirtualFrame frame, PFrame self,
136178
@Cached("create()") CodeNodes.CreateCodeNode createCodeNode) {
137179
RootCallTarget ct = self.getTarget();
138180
if (ct != null) {
@@ -144,6 +186,10 @@ Object get(VirtualFrame frame, PFrame self,
144186
"<internal>",
145187
"<internal>", -1, new byte[0]);
146188
}
189+
190+
public static GetCodeNode create() {
191+
return FrameBuiltinsFactory.GetCodeNodeFactory.create(new ReadArgumentNode[0]);
192+
}
147193
}
148194

149195
@Builtin(name = "f_locals", minNumOfPositionalArgs = 1, isGetter = true)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/frame/PFrame.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,10 @@ public int getLine() {
226226
} else {
227227
SourceSection sourceSection = location.getEncapsulatingSourceSection();
228228
if (sourceSection == null) {
229-
line = -1;
229+
return -1;
230230
} else {
231-
line = sourceSection.getStartLine();
231+
// The location can change, so we shouldn't cache the value
232+
return sourceSection.getStartLine();
232233
}
233234
}
234235
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/frame/ReadCallerFrameNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ private PFrame.Reference walkLevels(VirtualFrame frame, PFrame.Reference startFr
131131
return PArguments.getCurrentFrameInfo(callerFrame);
132132
}
133133
return PFrame.Reference.EMPTY;
134-
} else if (!(skipInternal && PRootNode.isPythonInternal(callerInfo.getCallNode().getRootNode()))) {
134+
} else if (!(skipInternal && (callerInfo.getCallNode() == null || PRootNode.isPythonInternal(callerInfo.getCallNode().getRootNode())))) {
135135
i++;
136136
}
137137
currentFrame = callerInfo;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/FunctionRootNode.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public class FunctionRootNode extends PClosureFunctionRootNode {
7070
@Child private CalleeContext calleeContext = CalleeContext.create();
7171

7272
private final ExpressionNode uninitializedBody;
73-
private final boolean isRewritten;
73+
private boolean isPythonInternal;
7474

7575
public FunctionRootNode(PythonLanguage language, SourceSection sourceSection, String functionName, boolean isGenerator, boolean isRewritten, FrameDescriptor frameDescriptor,
7676
ExpressionNode uninitializedBody, ExecutionCellSlots executionCellSlots, Signature signature) {
@@ -85,7 +85,7 @@ public FunctionRootNode(PythonLanguage language, SourceSection sourceSection, St
8585
// "uninitializedBody" is never modified or executed
8686
this.uninitializedBody = uninitializedBody;
8787
this.generatorFrameProfile = isGenerator ? ValueProfile.createClassProfile() : null;
88-
this.isRewritten = isRewritten;
88+
this.isPythonInternal = isRewritten;
8989
}
9090

9191
/**
@@ -99,7 +99,7 @@ private FunctionRootNode(FunctionRootNode other) {
9999
this.functionName = other.functionName;
100100
this.isGenerator = other.isGenerator;
101101
this.generatorFrameProfile = other.isGenerator ? ValueProfile.createClassProfile() : null;
102-
this.isRewritten = other.isRewritten;
102+
this.isPythonInternal = other.isPythonInternal;
103103
this.uninitializedBody = other.uninitializedBody;
104104
}
105105

@@ -110,7 +110,7 @@ protected boolean isCloneUninitializedSupported() {
110110

111111
@Override
112112
protected RootNode cloneUninitialized() {
113-
return new FunctionRootNode(PythonLanguage.getCurrent(), getSourceSection(), functionName, isGenerator, isRewritten, getFrameDescriptor(), uninitializedBody, executionCellSlots,
113+
return new FunctionRootNode(PythonLanguage.getCurrent(), getSourceSection(), functionName, isGenerator, isPythonInternal, getFrameDescriptor(), uninitializedBody, executionCellSlots,
114114
getSignature());
115115
}
116116

@@ -206,18 +206,18 @@ public boolean isInternal() {
206206
return sourceSection != null && sourceSection.getSource().isInternal();
207207
}
208208

209-
public boolean isRewritten() {
210-
return isRewritten;
211-
}
212-
213209
@Override
214210
public void initializeFrame(VirtualFrame frame) {
215211
initClosureAndCellVars(frame);
216212
}
217213

218214
@Override
219215
public boolean isPythonInternal() {
220-
return isRewritten;
216+
return isPythonInternal;
217+
}
218+
219+
public void setPythonInternal(boolean pythonInternal) {
220+
isPythonInternal = pythonInternal;
221221
}
222222

223223
public ExecutionCellSlots getExecutionCellSlots() {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/generator/GeneratorTryExceptNode.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ public void executeVoid(VirtualFrame frame) {
8989
getBody().executeVoid(frame);
9090
} catch (PException exception) {
9191
gen.setActive(frame, exceptFlag, true);
92-
catchExceptionInGeneratorFirstTime(frame, exception);
92+
if (!catchExceptionInGeneratorFirstTime(frame, exception)) {
93+
throw exception;
94+
}
9395
reset(frame);
9496
return;
9597
} catch (ControlFlowException e) {
@@ -98,7 +100,9 @@ public void executeVoid(VirtualFrame frame) {
98100
PException pe = wrapJavaExceptionIfApplicable(e);
99101
if (pe != null) {
100102
gen.setActive(frame, exceptFlag, true);
101-
catchExceptionInGeneratorFirstTime(frame, pe);
103+
if (!catchExceptionInGeneratorFirstTime(frame, pe)) {
104+
throw pe.getExceptionForReraise();
105+
}
102106
reset(frame);
103107
return;
104108
} else {
@@ -112,7 +116,7 @@ public void executeVoid(VirtualFrame frame) {
112116
}
113117

114118
@ExplodeLoop
115-
private void catchExceptionInGeneratorFirstTime(VirtualFrame frame, PException exception) {
119+
private boolean catchExceptionInGeneratorFirstTime(VirtualFrame frame, PException exception) {
116120
boolean wasHandled = false;
117121
ExceptNode[] exceptNodes = getExceptNodes();
118122
// we haven't found the matching node, yet, start searching
@@ -132,10 +136,7 @@ private void catchExceptionInGeneratorFirstTime(VirtualFrame frame, PException e
132136
}
133137
}
134138
}
135-
if (!wasHandled) {
136-
// we tried and haven't found a matching except node
137-
throw exception;
138-
}
139+
return wasHandled;
139140
}
140141

141142
@ExplodeLoop
@@ -173,7 +174,7 @@ private void runExceptionHandler(VirtualFrame frame, PException exception, Excep
173174
throw e;
174175
}
175176
tryChainExceptionFromHandler(handlerException, exception);
176-
throw handlerException;
177+
throw handlerException.getExceptionForReraise();
177178
} finally {
178179
restoreExceptionState(frame, savedExceptionState);
179180
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/generator/GeneratorTryFinallyNode.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ public void executeVoid(VirtualFrame frame) {
112112
if (activeException != null) {
113113
tryChainExceptionFromHandler(handlerException, activeException);
114114
}
115-
throw handlerException;
115+
throw handlerException.getExceptionForReraise();
116116
} finally {
117117
if (activeException != null) {
118118
restoreExceptionState(frame, savedExceptionState);

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ public abstract class ExceptionHandlingStatementNode extends StatementNode {
7070
@Child private PythonObjectFactory ofactory;
7171
@CompilationFinal private LoopConditionProfile contextChainHandledProfile;
7272
@CompilationFinal private LoopConditionProfile contextChainContextProfile;
73-
@CompilationFinal private Boolean shouldCatchAllExceptions;
7473
@CompilationFinal private ContextReference<PythonContext> contextRef;
7574
@CompilationFinal private LanguageReference<PythonLanguage> languageRef;
7675

@@ -199,8 +198,7 @@ public static PException wrapJavaException(Throwable e, Node node, PBaseExceptio
199198
pe.setHideLocation(true);
200199
// Re-attach truffle stacktrace
201200
moveTruffleStackTrace(e, pe);
202-
// Create a new traceback chain, because the current one has been finalized by Truffle
203-
return pe.getExceptionForReraise();
201+
return pe;
204202
}
205203

206204
protected final PException wrapJavaExceptionIfApplicable(Throwable e) {

0 commit comments

Comments
 (0)