44
44
import static com .oracle .graal .python .nodes .SpecialMethodNames .__STR__ ;
45
45
import static com .oracle .graal .python .runtime .exception .PythonErrorType .SystemExit ;
46
46
47
- import java .io .IOException ;
48
-
49
47
import com .oracle .graal .python .PythonLanguage ;
50
48
import com .oracle .graal .python .builtins .objects .PNone ;
51
49
import com .oracle .graal .python .builtins .objects .dict .PDict ;
52
- import com .oracle .graal .python .builtins .objects .exception .GetExceptionTracebackNode ;
53
50
import com .oracle .graal .python .builtins .objects .exception .PBaseException ;
54
51
import com .oracle .graal .python .builtins .objects .frame .PFrame ;
55
52
import com .oracle .graal .python .builtins .objects .function .PArguments ;
56
- import com .oracle .graal .python .builtins .objects .function .PKeyword ;
57
53
import com .oracle .graal .python .builtins .objects .module .PythonModule ;
58
54
import com .oracle .graal .python .builtins .objects .object .PythonObjectLibrary ;
59
- import com .oracle .graal .python .builtins .objects .traceback .LazyTraceback ;
60
- import com .oracle .graal .python .builtins .objects .traceback .PTraceback ;
61
- import com .oracle .graal .python .nodes .BuiltinNames ;
62
- import com .oracle .graal .python .nodes .call .CallNode ;
63
- import com .oracle .graal .python .nodes .call .special .LookupAndCallUnaryNode ;
64
55
import com .oracle .graal .python .nodes .object .IsBuiltinClassProfile ;
65
56
import com .oracle .graal .python .nodes .statement .ExceptionHandlingStatementNode ;
66
57
import com .oracle .graal .python .nodes .util .CannotCastException ;
67
58
import com .oracle .graal .python .nodes .util .CastToJavaLongLossyNode ;
68
59
import com .oracle .graal .python .runtime .ExecutionContext .IndirectCalleeContext ;
69
60
import com .oracle .graal .python .runtime .PythonContext ;
70
- import com .oracle .graal .python .runtime .PythonCore ;
71
61
import com .oracle .graal .python .runtime .PythonOptions ;
72
62
import com .oracle .graal .python .runtime .exception .ExceptionUtils ;
73
63
import com .oracle .graal .python .runtime .exception .PException ;
@@ -94,11 +84,6 @@ public class TopLevelExceptionHandler extends RootNode {
94
84
@ CompilationFinal private LanguageReference <PythonLanguage > language ;
95
85
@ CompilationFinal private ContextReference <PythonContext > context ;
96
86
97
- @ Child private LookupAndCallUnaryNode callStrNode = LookupAndCallUnaryNode .create (__STR__ );
98
- @ Child private CallNode exceptionHookCallNode = CallNode .create ();
99
- @ Child private GetExceptionTracebackNode getExceptionTracebackNode ;
100
- @ Child private PythonObjectFactory pythonObjectFactory ;
101
-
102
87
public TopLevelExceptionHandler (PythonLanguage language , RootNode child ) {
103
88
super (language );
104
89
this .sourceSection = child .getSourceSection ();
@@ -129,48 +114,52 @@ private PythonContext getContext() {
129
114
return context .get ();
130
115
}
131
116
132
- private PythonObjectFactory factory () {
133
- if (pythonObjectFactory == null ) {
134
- CompilerDirectives .transferToInterpreterAndInvalidate ();
135
- pythonObjectFactory = insert (PythonObjectFactory .create ());
136
- }
137
- return pythonObjectFactory ;
138
- }
139
-
140
117
@ Override
141
118
public Object execute (VirtualFrame frame ) {
142
119
if (exception != null ) {
143
- printExc (frame , exception .getEscapedException ());
144
- return null ;
120
+ throw handlePythonException (exception .getEscapedException ());
145
121
} else {
146
122
assert getContext ().getCurrentException () == null ;
147
123
try {
148
124
return run (frame );
149
125
} catch (PException e ) {
150
126
assert !PArguments .isPythonFrame (frame );
151
- PBaseException pythonException = e .getEscapedException ();
152
- printExc (frame , pythonException );
153
- return null ;
127
+ throw handlePythonException (e .getEscapedException ());
154
128
} catch (StackOverflowError e ) {
155
- PException pe = ExceptionHandlingStatementNode .wrapJavaException (e , this , factory ().createBaseException (RecursionError , "maximum recursion depth exceeded" , new Object []{}));
156
- PBaseException pythonException = pe .getUnreifiedException ();
157
- printExc (frame , pythonException );
158
- return null ;
129
+ PBaseException newException = PythonObjectFactory .getUncached ().createBaseException (RecursionError , "maximum recursion depth exceeded" , new Object []{});
130
+ PException pe = ExceptionHandlingStatementNode .wrapJavaException (e , this , newException );
131
+ throw handlePythonException (pe .getEscapedException ());
159
132
} catch (Exception e ) {
160
- handleException (e );
133
+ handleJavaException (e );
161
134
throw e ;
162
135
}
163
136
}
164
137
}
165
138
166
139
@ TruffleBoundary
167
- private void handleException (Exception e ) {
140
+ private PException handlePythonException (PBaseException pythonException ) {
141
+ if (IsBuiltinClassProfile .profileClassSlowPath (PythonObjectLibrary .getUncached ().getLazyPythonClass (pythonException ), SystemExit )) {
142
+ handleSystemExit (pythonException );
143
+ }
144
+ ExceptionUtils .printExceptionTraceback (getContext (), pythonException );
145
+ if (PythonOptions .isPExceptionWithJavaStacktrace (getPythonLanguage ())) {
146
+ ExceptionUtils .printJavaStackTrace (pythonException .getException ());
147
+ }
148
+ if (getSourceSection ().getSource ().isInteractive ()) {
149
+ throw pythonException .getExceptionForReraise (pythonException .getTraceback ());
150
+ } else {
151
+ throw new PythonExitException (this , 1 );
152
+ }
153
+ }
154
+
155
+ @ TruffleBoundary
156
+ private void handleJavaException (Exception e ) {
168
157
try {
169
158
boolean exitException = InteropLibrary .getUncached ().isException (e ) && InteropLibrary .getUncached ().getExceptionType (e ) == ExceptionType .EXIT ;
170
159
if (!exitException ) {
171
160
ExceptionUtils .printPythonLikeStackTrace (e );
172
161
if (PythonOptions .isWithJavaStacktrace (getPythonLanguage ())) {
173
- printStackTrace (e );
162
+ e . printStackTrace ();
174
163
}
175
164
}
176
165
} catch (UnsupportedMessageException unsupportedMessageException ) {
@@ -183,59 +172,8 @@ public SourceSection getSourceSection() {
183
172
return sourceSection ;
184
173
}
185
174
186
- /**
187
- * This function is kind-of analogous to PyErr_PrintEx. TODO (timfel): Figure out if we should
188
- * move this somewhere else
189
- */
190
- private void printExc (VirtualFrame frame , PBaseException pythonException ) {
191
- CompilerDirectives .transferToInterpreter ();
192
- PythonContext theContext = getContext ();
193
- PythonCore core = theContext .getCore ();
194
- if (IsBuiltinClassProfile .profileClassSlowPath (PythonObjectLibrary .getUncached ().getLazyPythonClass (pythonException ), SystemExit )) {
195
- handleSystemExit (frame , pythonException );
196
- }
197
-
198
- PBaseException value = pythonException ;
199
- Object type = PythonObjectLibrary .getUncached ().getLazyPythonClass (value );
200
- PTraceback execute = ensureGetTracebackNode ().execute (frame , value );
201
- Object tb = execute != null ? execute : PNone .NONE ;
202
-
203
- PythonModule sys = core .lookupBuiltinModule ("sys" );
204
- sys .setAttribute (BuiltinNames .LAST_TYPE , type );
205
- sys .setAttribute (BuiltinNames .LAST_VALUE , value );
206
- sys .setAttribute (BuiltinNames .LAST_TRACEBACK , tb );
207
-
208
- Object hook = sys .getAttribute (BuiltinNames .EXCEPTHOOK );
209
- if (theContext .getOption (PythonOptions .AlwaysRunExcepthook )) {
210
- if (hook != PNone .NO_VALUE ) {
211
- try {
212
- // Note: it is important to pass frame 'null' because that will cause the
213
- // CallNode to tread the invoke like a foreign call and access the top frame ref
214
- // in the context.
215
- exceptionHookCallNode .execute (null , hook , new Object []{type , value , tb }, PKeyword .EMPTY_KEYWORDS );
216
- } catch (PException internalError ) {
217
- // More complex handling of errors in exception printing is done in our
218
- // Python code, if we get here, we just fall back to the launcher
219
- throw pythonException .getExceptionForReraise (pythonException .getTraceback ());
220
- }
221
- if (PythonOptions .isPExceptionWithJavaStacktrace (getPythonLanguage ())) {
222
- printJavaStackTrace (pythonException .getException ());
223
- }
224
- if (!getSourceSection ().getSource ().isInteractive ()) {
225
- throw new PythonExitException (this , 1 );
226
- }
227
- } else {
228
- try {
229
- theContext .getEnv ().err ().write ("sys.excepthook is missing\n " .getBytes ());
230
- } catch (IOException ioException ) {
231
- ioException .printStackTrace ();
232
- }
233
- }
234
- }
235
- throw pythonException .getExceptionForReraise (pythonException .getTraceback ());
236
- }
237
-
238
- private void handleSystemExit (VirtualFrame frame , PBaseException pythonException ) {
175
+ @ TruffleBoundary
176
+ private void handleSystemExit (PBaseException pythonException ) {
239
177
PythonContext theContext = getContext ();
240
178
if (theContext .getOption (PythonOptions .InspectFlag ) && !getSourceSection ().getSource ().isInteractive ()) {
241
179
// Don't exit if -i flag was given and we're not yet running interactively
@@ -255,43 +193,15 @@ private void handleSystemExit(VirtualFrame frame, PBaseException pythonException
255
193
}
256
194
if (theContext .getOption (PythonOptions .AlwaysRunExcepthook )) {
257
195
// If we failed to dig out the exit code we just print and leave
196
+ PythonObjectLibrary lib = PythonObjectLibrary .getUncached ();
258
197
Object stderr = theContext .getCore ().getStderr ();
259
- Object message = callStrNode . executeObject ( frame , pythonException );
260
- PythonObjectLibrary . getUncached () .lookupAndCallRegularMethod (stderr , null , "write" , message );
198
+ Object message = lib . lookupAndCallSpecialMethod ( pythonException , null , __STR__ );
199
+ lib .lookupAndCallRegularMethod (stderr , null , "write" , message );
261
200
throw new PythonExitException (this , 1 );
262
201
}
263
202
throw pythonException .getExceptionForReraise (pythonException .getTraceback ());
264
203
}
265
204
266
- @ TruffleBoundary
267
- private static void printJavaStackTrace (PException e ) {
268
- LazyTraceback traceback = e .getTraceback ();
269
- while (traceback != null && traceback .getNextChain () != null ) {
270
- traceback = traceback .getNextChain ();
271
- }
272
- if (traceback != null ) {
273
- PException exception = traceback .getException ();
274
- if (exception .getCause () != null && exception .getCause ().getStackTrace ().length != 0 ) {
275
- exception .getCause ().printStackTrace ();
276
- } else {
277
- exception .printStackTrace ();
278
- }
279
- }
280
- }
281
-
282
- @ TruffleBoundary
283
- private static void printStackTrace (Throwable e ) {
284
- e .printStackTrace ();
285
- }
286
-
287
- private GetExceptionTracebackNode ensureGetTracebackNode () {
288
- if (getExceptionTracebackNode == null ) {
289
- CompilerDirectives .transferToInterpreterAndInvalidate ();
290
- getExceptionTracebackNode = insert (GetExceptionTracebackNode .create ());
291
- }
292
- return getExceptionTracebackNode ;
293
- }
294
-
295
205
private Object run (VirtualFrame frame ) {
296
206
Object [] arguments = PArguments .create (frame .getArguments ().length );
297
207
for (int i = 0 ; i < frame .getArguments ().length ; i ++) {
0 commit comments