3535import com .oracle .truffle .api .interop .InteropLibrary ;
3636import com .oracle .truffle .api .interop .NodeLibrary ;
3737import com .oracle .truffle .api .interop .UnsupportedMessageException ;
38+ import com .oracle .truffle .api .nodes .ControlFlowException ;
3839import com .oracle .truffle .api .nodes .Node ;
3940import com .oracle .truffle .api .source .Source ;
4041
@@ -68,73 +69,62 @@ private InsightHookNode(InsightInstrument.Key key, InsightInstrument insight, Ev
6869
6970 @ Override
7071 protected void onEnter (VirtualFrame frame ) {
71- final int len = key .functionsMaxCount ();
72- CompilerAsserts .partialEvaluationConstant (len );
73- final InsightPerContext ipc = insight .findCtx ();
74- for (int i = 0 ; i < len ; i ++) {
75- InsightFilter .Data data = (InsightFilter .Data ) ipc .functionFor (key , i );
76- if (!isApplicable (data , AgentType .ENTER )) {
77- continue ;
78- }
79- final EventContextObject eco = eventCtxObj ();
80- try {
81- enterDispatch .execute (data .fn , eco , getVariables (frame , true , null ));
82- } catch (InteropException ex ) {
83- throw EventContextObject .wrap (data .fn , 2 , ex );
84- } catch (RuntimeException ex ) {
85- throw EventContextObject .rethrow (ex , exceptionDispatch );
86- }
87- }
72+ loopHooks (frame , AgentType .ENTER , null );
8873 }
8974
9075 @ Override
9176 protected void onReturnValue (VirtualFrame frame , Object returnValue ) {
92- final int len = key .functionsMaxCount ();
93- CompilerAsserts .partialEvaluationConstant (len );
94- final InsightPerContext ipc = insight .findCtx ();
95- for (int i = 0 ; i < len ; i ++) {
96- InsightFilter .Data data = (InsightFilter .Data ) ipc .functionFor (key , i );
97- if (!isApplicable (data , AgentType .RETURN )) {
98- continue ;
99- }
100- final EventContextObject eco = eventCtxObj ();
101- try {
102- exitDispatch .execute (data .fn , eco , getVariables (frame , false , returnValue ));
103- } catch (InteropException ex ) {
104- throw EventContextObject .wrap (data .fn , 2 , ex );
105- } catch (RuntimeException ex ) {
106- throw EventContextObject .rethrow (ex , exceptionDispatch );
107- }
108- }
77+ loopHooks (frame , AgentType .RETURN , returnValue );
10978 }
11079
11180 @ Override
11281 protected void onReturnExceptional (VirtualFrame frame , Throwable exception ) {
82+ loopHooks (frame , AgentType .RETURN , null );
83+ }
84+
85+ @ Override
86+ protected Object onUnwind (VirtualFrame frame , Object info ) {
87+ return info ;
88+ }
89+
90+ private void loopHooks (VirtualFrame frame , final AgentType type , Object returnValue ) throws RuntimeException , ThreadDeath {
11391 final int len = key .functionsMaxCount ();
11492 CompilerAsserts .partialEvaluationConstant (len );
11593 final InsightPerContext ipc = insight .findCtx ();
94+ ReturnNow returnNow = null ;
11695 for (int i = 0 ; i < len ; i ++) {
11796 InsightFilter .Data data = (InsightFilter .Data ) ipc .functionFor (key , i );
118- if (!isApplicable (data , AgentType . RETURN )) {
97+ if (!isApplicable (data , type )) {
11998 continue ;
12099 }
121100 final EventContextObject eco = eventCtxObj ();
122101 try {
123- exitDispatch .execute (data .fn , eco , getVariables (frame , false , null ));
102+ exitDispatch .execute (data .fn , eco , getVariables (frame , type == AgentType .ENTER , returnValue ));
103+ } catch (ReturnNow ex ) {
104+ if (returnNow == null ) {
105+ returnNow = ex ;
106+ }
124107 } catch (InteropException ex ) {
125108 throw EventContextObject .wrap (data .fn , 2 , ex );
126109 } catch (RuntimeException ex ) {
127110 throw EventContextObject .rethrow (ex , exceptionDispatch );
128111 }
129112 }
113+ if (returnNow != null ) {
114+ throw ctx .createUnwind (NullObject .nullCheck (returnNow .returnValue ));
115+ }
130116 }
131117
132- @ Override
133- protected Object onUnwind (VirtualFrame frame , Object info ) {
134- return info ;
118+ private static final class ReturnNow extends ControlFlowException {
119+ static final long serialVersionUID = 49092343L ;
120+ final Object returnValue ;
121+
122+ ReturnNow (Object returnValue ) {
123+ this .returnValue = returnValue ;
124+ }
135125 }
136126
137- static ThreadDeath returnNow (EventContext context , Object [] args ) throws ArityException , ThreadDeath {
127+ static ControlFlowException returnNow (Object [] args ) throws ArityException {
138128 Object returnValue ;
139129 switch (args .length ) {
140130 case 0 :
@@ -146,7 +136,7 @@ static ThreadDeath returnNow(EventContext context, Object[] args) throws ArityEx
146136 default :
147137 throw ArityException .create (1 , 1 , args .length );
148138 }
149- return context . createUnwind ( NullObject . nullCheck ( returnValue ) );
139+ return new ReturnNow ( returnValue );
150140 }
151141
152142 private Object getVariables (VirtualFrame frame , boolean nodeEnter , Object returnValue ) {
0 commit comments