48
48
import com .oracle .graal .python .builtins .objects .cext .CExtNodes .PCallCapiFunction ;
49
49
import com .oracle .graal .python .builtins .objects .cext .DynamicObjectNativeWrapper .ToPyObjectNode ;
50
50
import com .oracle .graal .python .builtins .objects .dict .PDict ;
51
+ import com .oracle .graal .python .builtins .objects .exception .GetTracebackNode ;
52
+ import com .oracle .graal .python .builtins .objects .exception .GetTracebackNodeGen ;
51
53
import com .oracle .graal .python .builtins .objects .exception .PBaseException ;
54
+ import com .oracle .graal .python .builtins .objects .function .PArguments ;
55
+ import com .oracle .graal .python .builtins .objects .function .Signature ;
52
56
import com .oracle .graal .python .builtins .objects .traceback .PTraceback ;
53
57
import com .oracle .graal .python .builtins .objects .type .PythonAbstractClass ;
54
58
import com .oracle .graal .python .builtins .objects .type .PythonClass ;
55
59
import com .oracle .graal .python .nodes .PNodeWithContext ;
56
60
import com .oracle .graal .python .nodes .PRaiseNode ;
61
+ import com .oracle .graal .python .nodes .PRootNode ;
62
+ import com .oracle .graal .python .nodes .call .GenericInvokeNode ;
57
63
import com .oracle .graal .python .nodes .object .GetClassNode ;
64
+ import com .oracle .graal .python .runtime .ExecutionContext .CalleeContext ;
58
65
import com .oracle .graal .python .runtime .PythonContext ;
59
66
import com .oracle .graal .python .runtime .exception .PException ;
60
67
import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
61
68
import com .oracle .truffle .api .Assumption ;
69
+ import com .oracle .truffle .api .CompilerDirectives ;
62
70
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
71
+ import com .oracle .truffle .api .RootCallTarget ;
72
+ import com .oracle .truffle .api .TruffleLanguage ;
63
73
import com .oracle .truffle .api .dsl .Cached ;
64
74
import com .oracle .truffle .api .dsl .Cached .Exclusive ;
65
75
import com .oracle .truffle .api .dsl .Cached .Shared ;
66
76
import com .oracle .truffle .api .dsl .CachedContext ;
67
77
import com .oracle .truffle .api .dsl .GenerateUncached ;
68
78
import com .oracle .truffle .api .dsl .ImportStatic ;
69
79
import com .oracle .truffle .api .dsl .Specialization ;
80
+ import com .oracle .truffle .api .frame .VirtualFrame ;
70
81
import com .oracle .truffle .api .interop .InteropLibrary ;
71
82
import com .oracle .truffle .api .interop .UnknownIdentifierException ;
72
83
import com .oracle .truffle .api .interop .UnsupportedMessageException ;
73
84
import com .oracle .truffle .api .library .CachedLibrary ;
74
85
import com .oracle .truffle .api .library .ExportLibrary ;
75
86
import com .oracle .truffle .api .library .ExportMessage ;
87
+ import com .oracle .truffle .api .profiles .BranchProfile ;
76
88
import com .oracle .truffle .llvm .spi .NativeTypeLibrary ;
77
89
78
90
@ ExportLibrary (InteropLibrary .class )
@@ -136,6 +148,9 @@ protected Object readMember(String member,
136
148
@ ImportStatic (PThreadState .class )
137
149
@ GenerateUncached
138
150
abstract static class ThreadStateReadNode extends PNodeWithContext {
151
+
152
+ private static GetTracebackRootNode getTracebackRootNode ;
153
+
139
154
public abstract Object execute (Object key );
140
155
141
156
@ Specialization (guards = "eq(key, CUR_EXC_TYPE)" )
@@ -162,12 +177,16 @@ PBaseException doCurExcValue(@SuppressWarnings("unused") String key,
162
177
}
163
178
164
179
@ Specialization (guards = "eq(key, CUR_EXC_TRACEBACK)" )
165
- PTraceback doCurExcTraceback (@ SuppressWarnings ("unused" ) String key ,
166
- @ Shared ("context" ) @ CachedContext (PythonLanguage .class ) PythonContext context ) {
180
+ Object doCurExcTraceback (@ SuppressWarnings ("unused" ) String key ,
181
+ @ Shared ("context" ) @ CachedContext (PythonLanguage .class ) PythonContext context ,
182
+ @ Shared ("invokeNode" ) @ Cached GenericInvokeNode invokeNode ) {
167
183
PException currentException = context .getCurrentException ();
168
184
if (currentException != null ) {
169
185
PBaseException exceptionObject = currentException .getExceptionObject ();
170
- return exceptionObject .getTraceback ();
186
+ // we use 'GetTracebackNode' via a call to have a frame
187
+ Object [] arguments = PArguments .create (1 );
188
+ PArguments .setArgument (arguments , 0 , exceptionObject );
189
+ return invokeNode .execute (null , ensureCallTarget (context .getLanguage ()), arguments );
171
190
}
172
191
return null ;
173
192
}
@@ -196,12 +215,16 @@ PBaseException doExcValue(@SuppressWarnings("unused") String key,
196
215
}
197
216
198
217
@ Specialization (guards = "eq(key, EXC_TRACEBACK)" )
199
- PTraceback doExcTraceback (@ SuppressWarnings ("unused" ) String key ,
200
- @ Shared ("context" ) @ CachedContext (PythonLanguage .class ) PythonContext context ) {
218
+ Object doExcTraceback (@ SuppressWarnings ("unused" ) String key ,
219
+ @ Shared ("context" ) @ CachedContext (PythonLanguage .class ) PythonContext context ,
220
+ @ Shared ("invokeNode" ) @ Cached GenericInvokeNode invokeNode ) {
201
221
PException currentException = context .getCaughtException ();
202
222
if (currentException != null ) {
203
223
PBaseException exceptionObject = currentException .getExceptionObject ();
204
- return exceptionObject .getTraceback ();
224
+ // we use 'GetTracebackNode' via a call to have a frame
225
+ Object [] arguments = PArguments .create (1 );
226
+ PArguments .setArgument (arguments , 0 , exceptionObject );
227
+ return invokeNode .execute (null , ensureCallTarget (context .getLanguage ()), arguments );
205
228
}
206
229
return null ;
207
230
}
@@ -228,6 +251,13 @@ Object doPrev(@SuppressWarnings("unused") String key,
228
251
protected static boolean eq (String key , String expected ) {
229
252
return expected .equals (key );
230
253
}
254
+
255
+ private static RootCallTarget ensureCallTarget (PythonLanguage language ) {
256
+ if (getTracebackRootNode == null ) {
257
+ getTracebackRootNode = new GetTracebackRootNode (language );
258
+ }
259
+ return getTracebackRootNode .getCallTarget ();
260
+ }
231
261
}
232
262
233
263
// WRITE
@@ -441,4 +471,47 @@ protected static Assumption singleNativeContextAssumption() {
441
471
return PythonContext .getSingleNativeContextAssumption ();
442
472
}
443
473
}
474
+
475
+ private static final class GetTracebackRootNode extends PRootNode {
476
+
477
+ protected GetTracebackRootNode (TruffleLanguage <?> language ) {
478
+ super (language );
479
+ }
480
+
481
+ @ Child private GetTracebackNode getTracebackNode ;
482
+ @ Child private CalleeContext calleeContext = CalleeContext .create ();
483
+
484
+ private final BranchProfile profile = BranchProfile .create ();
485
+
486
+ @ Override
487
+ public Object execute (VirtualFrame frame ) {
488
+ CalleeContext .enter (frame , profile );
489
+ try {
490
+ if (getTracebackNode == null ) {
491
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
492
+ getTracebackNode = insert (GetTracebackNodeGen .create ());
493
+ }
494
+ PBaseException e = (PBaseException ) PArguments .getArgument (frame , 0 );
495
+ return getTracebackNode .execute (frame , e );
496
+ } finally {
497
+ calleeContext .exit (frame , this );
498
+ }
499
+ }
500
+
501
+ @ Override
502
+ public boolean isInternal () {
503
+ return true ;
504
+ }
505
+
506
+ @ Override
507
+ public Signature getSignature () {
508
+ return Signature .EMPTY ;
509
+ }
510
+
511
+ @ Override
512
+ public boolean isPythonInternal () {
513
+ return true ;
514
+ }
515
+
516
+ }
444
517
}
0 commit comments