JumpNode

Yields control flow to another part of the program through a "jump with arguments".

Jump nodes yield control to a target "place" in the program, while also carrying information. They can be seen as a (a) goto, (b) function application, (c) return statement or (d) synchronous message being sent to another process.

More...

Members

Functions

opEquals
bool opEquals(const(JumpNode) rhs)

Equivalence check.

opIndex
inout(InEdge)* opIndex(InEdge.ID slot)

See Node.opIndex.

toHash
hash_t toHash()

Semantic hash.

Properties

inEdges
InEdgeIterator!Callable inEdges [@property getter]

Provides an iterator over this node's in-edges.

outEdges
OutEdgeIterator!Callable outEdges [@property getter]

Provides an iterator over this node's out-edges.

Static functions

dispose
void dispose(JumpNode* self)

Frees all resources allocated by this node and sets it to an uninitialized state.

initialize
err_t initialize(JumpNode* self, uint n)

Initializes a jump node, must be later disposed.

Variables

arguments
OutEdge[] arguments;

Arguments to be sent into the continuation and later used inside a join pattern's body.

continuation
OutEdge continuation;

A data dependency on some live continuation.

control
InEdge control;

Incoming control flow which is about to be yielded to the target continuation.

Mixed In Members

From mixin NodeInheritance

opPostMove
void opPostMove(const(This) old)

Post-move adjusts in-edge slots' owner pointer.

Detailed Description

Gyre jumps differ from classic function calls because there is no implicit expectation of a "return"; this is CPS. If a caller expects return values (or even to take control back at all), it needs to set up a "return continuation" and pass that in as an argument as well, hoping that the subprocedure it is calling will (1) eventually receive messages on all of its other channels, triggering the join pattern; (2) execute the join's body to completion; and (3) have that body jump into the provided continuation as a way to come back (perhaps with a return value) to the calling code. This is not unlike what we (implicitly) assume of normal functions: their return depends on (1) whether it doesn't go into starvation while waiting for other threads; (2) whether it terminates; and (3) whether it actually has a return statement (it could call a C-like exit procedure instead, or throw an exception to another part of the call stack).

Jumps synchronize with each other when they cause a multiple-channel join pattern to trigger. Imagine a set of concurrent processes, each carrying a continuation corresponding to a different channel of some join pattern; once they've all jumped into their respective continuations, the join triggers and its body executes. Then, every event in those processes which happens before the jump, also happens before all events in the triggered join pattern's body. Notice that this does not necessarily apply to single-channel join patterns.

See Also