Skip to content

Commit

Permalink
Set up for triggering breakpoint for chained promises
Browse files Browse the repository at this point in the history
- TODO: for the sender (resolver) side implement stepping strategy in Truffle to get the location of the end of the message executed
- TODO: for the receiver side (resolution) resolved issue #57
  • Loading branch information
ctrlpz committed Nov 22, 2016
1 parent 6ccb6f1 commit fcb6c45
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 8 deletions.
7 changes: 6 additions & 1 deletion src/som/interpreter/actors/ResolvePromiseNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,17 @@ public SResolver selfResolution(final SResolver resolver, final SPromise result,
* Handle the case that a promise is resolved with another promise, which is not itself.
*/
@Specialization(guards = {"resolver.getPromise() != result"})
public SResolver chainedPromise(final SResolver resolver, final SPromise result, final boolean isBreakpointOnResolutionAtSender, final boolean isBreakpointOnResolutionAtRcvr) {
public SResolver chainedPromise(final VirtualFrame frame, final SResolver resolver, final SPromise result, final boolean isBreakpointOnResolutionAtSender, final boolean isBreakpointOnResolutionAtRcvr) {
assert resolver.assertNotCompleted();
SPromise promise = resolver.getPromise();
synchronized (promise) { // TODO: is this really deadlock free?
result.addChainedPromise(promise);
}

if (isBreakpointOnResolutionAtSender) {
haltNode.executeEvaluated(frame, result);
}

return resolver;
}

Expand Down
32 changes: 25 additions & 7 deletions src/som/interpreter/actors/SPromise.java
Original file line number Diff line number Diff line change
Expand Up @@ -308,34 +308,46 @@ public final boolean assertNotCompleted() {
return promise.assertNotCompleted();
}

/**
* Handles the case when a promise is resolved with a proper value
* and previously has been chained with other promises.
*
*/
// TODO: solve the TODO and then remove the TruffleBoundary, this might even need to go into a node
@TruffleBoundary
protected static void resolveChainedPromisesUnsync(final SPromise promise,
final Object result, final Actor current) {
final Object result, final Actor current, final boolean isBreakpointOnResolutionAtRcvr) {
// TODO: we should change the implementation of chained promises to
// always move all the handlers to the other promise, then we
// don't need to worry about traversing the chain, which can
// lead to a stack overflow.
// TODO: restore 10000 as parameter in testAsyncDeeplyChainedResolution
if (promise.chainedPromise != null) {
Object wrapped = promise.chainedPromise.owner.wrapForUse(result, current, null);
resolveAndTriggerListenersUnsynced(result, wrapped, promise.chainedPromise, current, false);
resolveMoreChainedPromisesUnsynced(promise, result, current);
resolveAndTriggerListenersUnsynced(result, wrapped, promise.chainedPromise, current, isBreakpointOnResolutionAtRcvr);
resolveMoreChainedPromisesUnsynced(promise, result, current, isBreakpointOnResolutionAtRcvr);
}
}

/**
* Resolve the other promises that has been chained to the first promise.
*/
@TruffleBoundary
private static void resolveMoreChainedPromisesUnsynced(final SPromise promise,
final Object result, final Actor current) {
final Object result, final Actor current, final boolean isBreakpointOnResolutionAtRcvr) {
if (promise.chainedPromiseExt != null) {

for (SPromise p : promise.chainedPromiseExt) {
Object wrapped = p.owner.wrapForUse(result, current, null);
resolveAndTriggerListenersUnsynced(result, wrapped, p, current, false);
resolveAndTriggerListenersUnsynced(result, wrapped, p, current, isBreakpointOnResolutionAtRcvr);
}
}
}

/**
* Resolution of a promise with a proper value.
* All callbacks for that promise are scheduled.
* If the promise was chained with other promises are also resolved.
*/
protected static void resolveAndTriggerListenersUnsynced(final Object result,
final Object wrapped, final SPromise p, final Actor current, final boolean isBreakpointOnResolutionAtRcvr) {
assert !(result instanceof SPromise);
Expand All @@ -357,10 +369,13 @@ protected static void resolveAndTriggerListenersUnsynced(final Object result,
}

scheduleAllUnsync(p, result, current, isBreakpointOnResolutionAtRcvr);
resolveChainedPromisesUnsync(p, result, current);
resolveChainedPromisesUnsync(p, result, current, isBreakpointOnResolutionAtRcvr);
}
}

/**
* Schedule all the callbacks for a promise.
*/
protected static void scheduleAllUnsync(final SPromise promise,
final Object result, final Actor current, final boolean isBreakpointOnResolutionAtRcvr) {
if (promise.whenResolved != null) {
Expand All @@ -369,6 +384,9 @@ protected static void scheduleAllUnsync(final SPromise promise,
}
}

/**
* Schedule whenResolved extensions corresponding to a promise.
*/
@TruffleBoundary
private static void scheduleExtensions(final SPromise promise,
final Object result, final Actor current, final boolean isBreakpointOnResolutionAtRcvr) {
Expand Down

0 comments on commit fcb6c45

Please sign in to comment.