45
45
import com .oracle .graal .python .PythonLanguage ;
46
46
import com .oracle .graal .python .builtins .Builtin ;
47
47
import com .oracle .graal .python .builtins .CoreFunctions ;
48
+ import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
48
49
import com .oracle .graal .python .builtins .PythonBuiltins ;
49
50
import com .oracle .graal .python .builtins .objects .PNone ;
51
+ import com .oracle .graal .python .builtins .objects .exception .PBaseException ;
50
52
import com .oracle .graal .python .builtins .objects .frame .PFrame ;
51
53
import com .oracle .graal .python .builtins .objects .function .PKeyword ;
54
+ import com .oracle .graal .python .builtins .objects .object .PythonObjectLibrary ;
52
55
import com .oracle .graal .python .nodes .call .CallNode ;
53
56
import com .oracle .graal .python .nodes .function .PythonBuiltinBaseNode ;
57
+ import com .oracle .graal .python .nodes .function .PythonBuiltinNode ;
54
58
import com .oracle .graal .python .nodes .function .builtins .PythonUnaryBuiltinNode ;
55
59
import com .oracle .graal .python .nodes .function .builtins .PythonVarargsBuiltinNode ;
60
+ import com .oracle .graal .python .nodes .object .IsBuiltinClassProfile ;
56
61
import com .oracle .graal .python .runtime .PythonContext ;
62
+ import com .oracle .graal .python .runtime .exception .ExceptionUtils ;
57
63
import com .oracle .graal .python .runtime .exception .PException ;
58
64
import com .oracle .graal .python .util .PythonUtils ;
59
65
import com .oracle .truffle .api .CompilerDirectives ;
66
+ import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
60
67
import com .oracle .truffle .api .TruffleLanguage ;
61
68
import com .oracle .truffle .api .TruffleLanguage .ContextReference ;
62
69
import com .oracle .truffle .api .dsl .GenerateNodeFactory ;
@@ -75,17 +82,16 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
75
82
@ Builtin (name = "register" , minNumOfPositionalArgs = 1 , takesVarArgs = true , takesVarKeywordArgs = true )
76
83
@ GenerateNodeFactory
77
84
abstract static class RegisterNode extends PythonVarargsBuiltinNode {
78
- private static class AtExitCallTarget extends RootNode {
85
+ private static class AtExitRootNode extends RootNode {
79
86
@ Child private CallNode callNode = CallNode .create ();
80
87
81
88
private final ContextReference <PythonContext > contextRef = lookupContextReference (PythonLanguage .class );
82
89
83
- protected AtExitCallTarget (TruffleLanguage <?> language ) {
90
+ protected AtExitRootNode (TruffleLanguage <?> language ) {
84
91
super (language );
85
92
}
86
93
87
94
@ Override
88
- @ SuppressWarnings ("try" )
89
95
public Object execute (VirtualFrame frame ) {
90
96
PythonContext context = contextRef .get ();
91
97
context .setTopFrameInfo (PFrame .Reference .EMPTY );
@@ -99,18 +105,35 @@ public Object execute(VirtualFrame frame) {
99
105
// from the context.
100
106
try {
101
107
return callNode .execute (null , callable , arguments , keywords );
108
+ } catch (PException e ) {
109
+ handleException (context , e );
110
+ throw e ;
102
111
} finally {
103
112
context .popTopFrameInfo ();
104
113
context .setCaughtException (null );
105
114
}
106
115
}
116
+
117
+ @ TruffleBoundary
118
+ private static void handleException (PythonContext context , PException e ) {
119
+ PBaseException pythonException = e .getEscapedException ();
120
+ PythonObjectLibrary lib = PythonObjectLibrary .getUncached ();
121
+ if (!IsBuiltinClassProfile .profileClassSlowPath (lib .getLazyPythonClass (pythonException ), PythonBuiltinClassType .SystemExit )) {
122
+ lib .lookupAndCallRegularMethod (context .getCore ().getStderr (), null , "write" , "Error in atexit._run_exitfuncs:\n " );
123
+ try {
124
+ ExceptionUtils .printExceptionTraceback (context , pythonException );
125
+ } catch (PException pe ) {
126
+ lib .lookupAndCallRegularMethod (context .getCore ().getStderr (), null , "write" , "Failed to print traceback\n " );
127
+ }
128
+ }
129
+ }
107
130
}
108
131
109
132
@ Specialization
110
133
Object register (Object callable , Object [] arguments , PKeyword [] keywords ) {
111
134
CompilerDirectives .transferToInterpreter ();
112
- AtExitCallTarget atExitCallTarget = new AtExitCallTarget (getContext ().getLanguage ());
113
- getContext ().registerShutdownHook (callable , arguments , keywords , PythonUtils .getOrCreateCallTarget (atExitCallTarget ));
135
+ AtExitRootNode atExitRootNode = new AtExitRootNode (getContext ().getLanguage ());
136
+ getContext ().registerAtexitHook (callable , arguments , keywords , PythonUtils .getOrCreateCallTarget (atExitRootNode ));
114
137
return callable ;
115
138
}
116
139
}
@@ -120,7 +143,36 @@ Object register(Object callable, Object[] arguments, PKeyword[] keywords) {
120
143
abstract static class UnregisterNode extends PythonUnaryBuiltinNode {
121
144
@ Specialization
122
145
Object register (Object callable ) {
123
- getContext ().deregisterShutdownHook (callable );
146
+ getContext ().unregisterAtexitHook (callable );
147
+ return PNone .NONE ;
148
+ }
149
+ }
150
+
151
+ @ Builtin (name = "_clear" )
152
+ @ GenerateNodeFactory
153
+ abstract static class ClearNode extends PythonBuiltinNode {
154
+ @ Specialization
155
+ Object clear () {
156
+ getContext ().clearAtexitHooks ();
157
+ return PNone .NONE ;
158
+ }
159
+ }
160
+
161
+ @ Builtin (name = "_ncallbacks" )
162
+ @ GenerateNodeFactory
163
+ abstract static class NCallbacksNode extends PythonBuiltinNode {
164
+ @ Specialization
165
+ int get () {
166
+ return getContext ().getAtexitHookCount ();
167
+ }
168
+ }
169
+
170
+ @ Builtin (name = "_run_exitfuncs" )
171
+ @ GenerateNodeFactory
172
+ abstract static class RunExitfuncsNode extends PythonBuiltinNode {
173
+ @ Specialization
174
+ Object run () {
175
+ getContext ().runAtexitHooks ();
124
176
return PNone .NONE ;
125
177
}
126
178
}
0 commit comments