graphAsync
will write a Graphviz DOT format file describing the
given generator or async/await block. The graph shows the
generator as a state machine with nodes that connect to each other.
If type
is something other than dot
graphAsync will then try to invoke Graphviz
dot` to turn the graph description into an image
file.
The green octagonal node is where the program starts, while red
"stop" and blue "return" are where it ends. Nodes in green type on
dark background show code that runs in the host language
unmodified; gray nodes implement control flow. Dark arrows carry a
value; gray edges carry no value. A "semicolon" node receives a
value and discards it.
Some nodes share a context with other nodes, shown by an enclosing
box. Contexts can have state variables, shown as a rectangular
record; orange edges from functions to variables represent writes;
blue edges represent reads.
Dashed edges represent a state transition that goes through a
trampoline handler. Dashed edges have a Unicode symbol representing
the type of trampoline; (DOUBLE VERTICAL BAR) for await/yield; (TOP
ARC ANTICLOCKWISE ARROW WITH PLUS) or (TOP ARC CLOCKWISE ARROW WITH
MINUS) to wind on or off an exception handler; (ANTICLOCKWISE
TRIANGLE-HEADED BOTTOM U-SHAPED ARROW) for a plain trampoline with
no side effects (done once per loop, to avoid overflowing the
stack.) Meanwhile, a thin edge connects to the trampoline handler.
(So the user-facing "yield" function registers a continuation to
the next step but actually calls the generator's yield handler.)