Generate the state machine, and wire the closure to call it
commitadd5fc1bf242d3c45f5fa8dd02723e0081d3e1c9
authorMichael Tingley <tingley@fb.com>
Mon, 24 Apr 2017 21:09:55 +0000 (24 14:09 -0700)
committerHhvm Bot <hhvm-bot@users.noreply.github.com>
Tue, 25 Apr 2017 00:23:39 +0000 (24 17:23 -0700)
tree0bc7f848a0ea4ae9f7c7fb4dd01d34948bc48970
parent0c7ec261e29ab4a127f8c6dedb34467f2eaea1a9
Generate the state machine, and wire the closure to call it

Summary:
This diff more closely matches the lowering to the sample implementation in D4878298. A few things happen:

1. The following **new** method is generated on the original class:

  function methodName_GeneratedStateMachine(
    ClassName_methodName_GeneratedClosure $closure,
    mixed $coroutineData,
    ?Exception $exception,
  ): CoroutineResult<ResultType> {
    throw new Exception("Coroutines are not yet implemented.");
  }

2. The closure has been significantly reworked. It now receives a delegate representing the aforementioned state machine, and uses that state machine to implement the resumption logic:

  class ClassName_methodName_GeneratedClosure
    implements CoroutineContinuation<mixed> {

    function __construct(
      CoroutineContinuation<ResultType> $coroutineContinuation_generated,
      private (function(
        ClassName_methodName_GeneratedClosure,
        mixed,
        ?Exception,
      ): CoroutineResult<mixed>) $stateMachineFunction,
    ) {}

    function resume(mixed $coroutineData): void {
      $stateMachineFunction = $this->stateMachineFunction;
      $stateMachineFunction($this, $coroutineData, null);
    }

    function resumeWithException(Exception $exception): void {
      $stateMachineFunction = $this->stateMachineFunction;
      $stateMachineFunction($this, null, $exception);
    }
  }

3. The original method is lowered similarly to before, however now it also passes in the state machine delegate method:

  public function methodName(
    CoroutineContinuation<ResultType> $coroutineContinuation_generated,
  ): CoroutineResult<ResultType> {
    new ClassName_methodName_GeneratedClosure(
      $coroutineContinuation_generated,
      inst_meth($this, "methodName_GeneratedStateMachine"),
    )->resume(null);
    return SuspendedCoroutineResult::create();
  }

Reviewed By: ericlippert

Differential Revision: D4935242

fbshipit-source-id: 7c9fe275f247203f30415eb2d49da85c35f19fdb
hphp/hack/src/parser/coroutine/coroutine_closure_generator.ml
hphp/hack/src/parser/coroutine/coroutine_lowerer.ml
hphp/hack/src/parser/coroutine/coroutine_method_lowerer.ml
hphp/hack/src/parser/coroutine/coroutine_state_machine_generator.ml [new file with mode: 0644]
hphp/hack/src/parser/coroutine/coroutine_syntax.ml