Pass generator body Func* to c_Continuation::alloc()
[hiphop-php.git] / hphp / runtime / ext / ext_continuation.h
blobf1799c8767226fb290af2af4e8e3198b6932713c
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
6 | Copyright (c) 1997-2010 The PHP Group |
7 +----------------------------------------------------------------------+
8 | This source file is subject to version 3.01 of the PHP license, |
9 | that is bundled with this package in the file LICENSE, and is |
10 | available through the world-wide-web at the following url: |
11 | http://www.php.net/license/3_01.txt |
12 | If you did not receive a copy of the PHP license and are unable to |
13 | obtain it through the world-wide-web, please send a note to |
14 | license@php.net so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+
18 #ifndef incl_HPHP_EXT_CONTINUATION_H_
19 #define incl_HPHP_EXT_CONTINUATION_H_
22 #include "hphp/runtime/base/base_includes.h"
23 #include "hphp/system/systemlib.h"
25 namespace HPHP {
26 ///////////////////////////////////////////////////////////////////////////////
28 FORWARD_DECLARE_CLASS_BUILTIN(Continuation);
29 FORWARD_DECLARE_CLASS_BUILTIN(ContinuationWaitHandle);
30 p_Continuation f_hphp_create_continuation(CStrRef clsname, CStrRef funcname, CStrRef origFuncName, CArrRef args = null_array);
32 ///////////////////////////////////////////////////////////////////////////////
33 // class Continuation
35 class c_Continuation : public ExtObjectData {
36 public:
37 DECLARE_CLASS_NO_ALLOCATION(Continuation, Continuation, ObjectData)
38 virtual void sweep();
39 void operator delete(void* p) {
40 c_Continuation* this_ = (c_Continuation*)p;
41 DELETEOBJSZ(this_->getObjectSize())(this_);
44 explicit c_Continuation(Class* cls = c_Continuation::s_cls);
45 ~c_Continuation();
47 public:
48 bool done() const { return o_subclassData.u8[0]; }
49 bool running() const { return o_subclassData.u8[1]; }
50 void setDone(bool done) { o_subclassData.u8[0] = done; }
51 void setRunning(bool running) { o_subclassData.u8[1] = running; }
52 static constexpr uint doneOffset() {
53 return offsetof(c_Continuation, o_subclassData);
55 static constexpr uint runningOffset() {
56 return offsetof(c_Continuation, o_subclassData) + 1;
59 void t___construct();
60 void t_update(int64_t label, CVarRef value);
61 Object t_getwaithandle();
62 int64_t t_getlabel();
63 Variant t_current();
64 int64_t t_key();
65 void t_next();
66 void t_rewind();
67 bool t_valid();
68 void t_send(CVarRef v);
69 void t_raise(CVarRef v);
70 String t_getorigfuncname();
71 String t_getcalledclass();
72 Variant t___clone();
74 static c_Continuation* alloc(const Func* origFunc, const Func* genFunc) {
75 assert(origFunc);
76 assert(genFunc);
78 size_t arOffset = getArOffset(genFunc);
79 size_t objectSize = arOffset + sizeof(ActRec);
80 c_Continuation* cont = (c_Continuation*)ALLOCOBJSZ(objectSize);
81 new ((void *)cont) c_Continuation();
82 cont->m_origFunc = const_cast<Func*>(origFunc);
83 cont->m_arPtr = (ActRec*)(uintptr_t(cont) + arOffset);
84 memset((void*)((uintptr_t)cont + sizeof(c_Continuation)), 0,
85 arOffset - sizeof(c_Continuation));
86 assert(cont->getObjectSize() == objectSize);
87 return cont;
90 static size_t getArOffset(const Func* genFunc) {
91 size_t arOffset =
92 sizeof(c_Continuation) +
93 sizeof(Iter) * genFunc->numIterators() +
94 sizeof(TypedValue) * genFunc->numLocals();
95 arOffset += sizeof(TypedValue) - 1;
96 arOffset &= ~(sizeof(TypedValue) - 1);
97 return arOffset;
100 protected: virtual bool php_sleep(Variant &ret);
101 public:
102 void call_next();
103 void call_send(TypedValue* v);
104 void call_raise(ObjectData* e);
106 inline void preNext() {
107 if (done()) {
108 throw_exception(Object(SystemLib::AllocExceptionObject(
109 "Continuation is already finished")));
111 if (running()) {
112 throw_exception(Object(SystemLib::AllocExceptionObject(
113 "Continuation is already running")));
115 setRunning(true);
116 ++m_index;
119 inline void startedCheck() {
120 if (m_index < 0LL) {
121 throw_exception(
122 Object(SystemLib::AllocExceptionObject("Need to call next() first")));
126 private:
127 size_t getObjectSize() {
128 return (char*)(m_arPtr + 1) - (char*)this;
131 public:
132 /* 32-bit o_id from ObjectData */
133 int32_t m_label;
134 int64_t m_index;
135 Variant m_value;
136 Variant m_received;
137 Func *m_origFunc;
138 ActRec* m_arPtr;
139 p_ContinuationWaitHandle m_waitHandle;
141 String& getCalledClass() { not_reached(); }
143 ActRec* actRec() {
144 return m_arPtr;
148 ///////////////////////////////////////////////////////////////////////////////
149 // class DummyContinuation
151 FORWARD_DECLARE_CLASS_BUILTIN(DummyContinuation);
152 class c_DummyContinuation : public ExtObjectData {
153 public:
154 DECLARE_CLASS(DummyContinuation, DummyContinuation, ObjectData)
156 // need to implement
157 public: c_DummyContinuation(Class* cls = c_DummyContinuation::s_cls);
158 public: ~c_DummyContinuation();
159 public: void t___construct();
160 public: Variant t_current();
161 public: int64_t t_key();
162 public: void t_next();
163 public: void t_rewind();
164 public: bool t_valid();
168 ///////////////////////////////////////////////////////////////////////////////
171 #endif // incl_HPHP_EXT_CONTINUATION_H_