Compute ambient coeffects and write to coeffects local
[hiphop-php.git] / hphp / runtime / vm / async-flow-stepper.h
blob8b8b02d84b3d2f5da0ec80ba913e4084c7c63ce5
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #pragma once
19 #include "hphp/runtime/vm/act-rec.h"
20 #include "hphp/runtime/vm/pc-filter.h"
22 namespace HPHP {
24 enum class AsyncStepperStage {
25 Disabled, // Not enabled.
26 StepOver, // Normal step over did not counter "await" opcode yet.
27 StepOverAwait, // In the middle of step over "await" opcode.
28 WaitResume, // Wait for resume internal breakpoint to hit.
31 // Indicate if AsyncFlowStepper has handled this opcode or not.
32 enum class AsyncStepHandleOpcodeResult {
33 Unhandled, // Not handled, other logic should handle it.
34 Handled, // Handled, other stepping logic should not handle it.
35 Completed, // Async stepping completes.
38 /**
39 * This stepper is responsible for doing logic async
40 * stepping over "await" opcode.
41 * Caller should call setup() before stepping
42 * and pass each step opcode to handleOpcode().
44 struct AsyncFlowStepper {
45 public:
46 void setup();
47 AsyncStepHandleOpcodeResult handleOpcode(PC pc);
48 void handleExceptionThrown();
49 bool handleExceptionHandler();
51 private:
52 void handleBlockedAwaitOpcode(PC pc);
53 bool isActRecOnAsyncStack(const ActRec* target);
54 void stepOverAwaitOpcode();
55 void captureResumeIdAfterAwait();
56 void setResumeInternalBreakpoint(PC pc);
57 bool didResumeBreakpointTrigger(PC pc);
58 const ActRec* getAsyncResumableId(const ActRec* fp);
59 void updateStepStartStackDepth();
60 bool isCompleted(PC pc);
61 void reset();
63 private:
64 AsyncStepperStage m_stage{AsyncStepperStage::Disabled};
65 // ActRec address that issued current async operation
66 // We used it to check if the completed async operation
67 // is the one we are current stepping.
68 ActRec* m_asyncResumableId{nullptr};
69 int m_stepStartStackDepth{0};
70 // Whether there is an exception thrown for current
71 // stepped async operation.
72 bool m_isCurrentAsyncStepException{false};
74 PCFilter m_stepRangeFlowFilter;
75 PCFilter m_awaitOpcodeBreakpointFilter;
76 PCFilter m_resumeBreakpointFilter;