Skip to content

Commit 1db91dc

Browse files
author
Jaroslav Tulach
committed
Implementing returnNow as ControlFlowException
1 parent 640c6f6 commit 1db91dc

4 files changed

Lines changed: 34 additions & 43 deletions

File tree

tools/src/com.oracle.truffle.tools.agentscript/src/com/oracle/truffle/tools/agentscript/impl/EventContextObject.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ static boolean isMemberReadable(EventContextObject obj, String member) {
8888
@ExportMessage
8989
static Object invokeMember(EventContextObject obj, String member, Object[] args) throws ArityException, UnknownIdentifierException, UnsupportedTypeException {
9090
if ("returnNow".equals(member)) {
91-
throw InsightHookNode.returnNow(obj.context, args);
91+
throw InsightHookNode.returnNow(args);
9292
}
9393
if ("returnValue".equals(member)) {
9494
if (args.length == 0 || !(args[0] instanceof VariablesObject)) {

tools/src/com.oracle.truffle.tools.agentscript/src/com/oracle/truffle/tools/agentscript/impl/InsightHookNode.java

Lines changed: 31 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import com.oracle.truffle.api.interop.InteropLibrary;
3636
import com.oracle.truffle.api.interop.NodeLibrary;
3737
import com.oracle.truffle.api.interop.UnsupportedMessageException;
38+
import com.oracle.truffle.api.nodes.ControlFlowException;
3839
import com.oracle.truffle.api.nodes.Node;
3940
import 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) {

vm/tests/all/agentscript/agent-sum.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
> js --insight=agent-summul2.js agent-sum.js
66
720
77
> js --insight=agent-sumneg.js agent-sum.js
8+
Original value was 21, but returning -21
89
-21
910
> js --insight=agent-summul2.js agent-fib.js
1011
Three is the result 80

vm/tests/all/agentscript/agent-sumneg.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ insight.on('return', function(ctx, frame) {
33
try {
44
ctx.returnNow(-positive);
55
} finally {
6-
ctx.returnNow('Never reached!');
6+
print(`Original value was ${positive}, but returning ${-positive}`);
77
}
88
}, {
99
roots: true,

0 commit comments

Comments
 (0)