2 +----------------------------------------------------------------------+
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 +----------------------------------------------------------------------+
19 #include "hphp/runtime/vm/class.h"
20 #include "hphp/util/optional.h"
23 ///////////////////////////////////////////////////////////////////////////////
30 ///////////////////////////////////////////////////////////////////////////////
31 struct RuntimeCoeffects
{
32 using storage_t
= uint16_t;
34 static RuntimeCoeffects
fromValue(uint16_t value
) {
35 return RuntimeCoeffects
{value
};
38 static RuntimeCoeffects
none() {
39 return RuntimeCoeffects::fromValue(0);
42 static RuntimeCoeffects
defaults();
43 static RuntimeCoeffects
pure();
44 static RuntimeCoeffects
zoned();
45 static RuntimeCoeffects
write_this_props();
46 static RuntimeCoeffects
write_props();
47 static RuntimeCoeffects
globals_leak_safe();
48 static RuntimeCoeffects
leak_safe_shallow();
50 // This function is a placeholder to indicate that the correct coeffect needs
51 // to be indentified and passed in its place
52 static RuntimeCoeffects
fixme() {
53 return RuntimeCoeffects::defaults();
56 static RuntimeCoeffects
automatic();
58 uint16_t value() const { return m_data
; }
60 const std::string
toString() const;
62 bool operator==(const RuntimeCoeffects
& o
) const {
63 return value() == o
.value();
65 bool operator!=(const RuntimeCoeffects
& o
) const {
69 // Checks whether provided coeffects in `this` can call
70 // required coeffects in `o`
71 bool canCall(const RuntimeCoeffects o
) const {
74 return ((~m_data
) & o
.m_data
) == 0;
77 bool canCallWithWarning(const RuntimeCoeffects
) const;
79 // This operator is equivalent to & of [coeffectA & coeffectB]
80 RuntimeCoeffects
& operator|=(const RuntimeCoeffects
);
82 template <typename SerDe
> void serde(SerDe
& sd
) {
85 template <typename SerDe
>
86 static RuntimeCoeffects
makeForSerde(SerDe
& sd
) {
89 return RuntimeCoeffects
{s
};
92 explicit RuntimeCoeffects(uint16_t data
) : m_data(data
) {}
96 struct CoeffectsAutoGuard
{
98 ~CoeffectsAutoGuard();
101 Optional
<RuntimeCoeffects
> savedCoeffects
;
107 struct StaticCoeffects
{
108 using storage_t
= RuntimeCoeffects::storage_t
;
110 const std::string
toString() const;
112 RuntimeCoeffects
toRequired() const;
114 static StaticCoeffects
fromValue(uint16_t value
) {
115 return StaticCoeffects
{value
};
118 uint16_t value() const { return m_data
; }
120 static StaticCoeffects
none() {
121 return StaticCoeffects::fromValue(0);
124 static StaticCoeffects
defaults();
125 static StaticCoeffects
write_this_props();
127 // This operator is equivalent to & of [coeffectA & coeffectB]
128 StaticCoeffects
& operator|=(const StaticCoeffects
);
130 template<class SerDe
>
131 void serde(SerDe
& sd
) {
136 // Returns the local bits
137 storage_t
locals() const;
140 explicit StaticCoeffects(uint16_t data
) : m_data(data
) {}
144 static_assert(sizeof(StaticCoeffects
) == sizeof(uint16_t), "");
145 static_assert(sizeof(StaticCoeffects
) == sizeof(RuntimeCoeffects
), "");
147 ///////////////////////////////////////////////////////////////////////////////
150 * Returns the combined static coeffects and escapes from a list of coeffects
152 std::pair
<StaticCoeffects
, RuntimeCoeffects
>
153 getCoeffectsInfoFromList(std::vector
<LowStringPtr
>, bool);
155 ///////////////////////////////////////////////////////////////////////////////
157 struct CoeffectRule final
{
162 struct ClosureParentScope
{};
163 struct GeneratorThis
{};
166 CoeffectRule() = default;
168 /////////////////////////////////////////////////////////////////////////////
169 // Native coeffect rules ////////////////////////////////////////////////////
171 CoeffectRule(FunParam
, uint32_t index
)
172 : m_type(Type::FunParam
)
176 CoeffectRule(CCParam
, uint32_t index
, const StringData
* ctx_name
)
177 : m_type(Type::CCParam
)
180 { assertx(ctx_name
); }
183 std::vector
<LowStringPtr
> types
,
184 const StringData
* ctx_name
)
185 : m_type(Type::CCThis
)
188 { assertx(ctx_name
); }
190 CoeffectRule(CCReified
,
193 std::vector
<LowStringPtr
> types
,
194 const StringData
* ctx_name
)
195 : m_type(Type::CCReified
)
196 , m_isClass(is_class
)
200 { assertx(ctx_name
); }
202 explicit CoeffectRule(ClosureParentScope
)
203 : m_type(Type::ClosureParentScope
)
206 explicit CoeffectRule(GeneratorThis
)
207 : m_type(Type::GeneratorThis
)
210 explicit CoeffectRule(Caller
)
211 : m_type(Type::Caller
)
214 static uint64_t getFunParam(TypedValue
, uint32_t);
216 RuntimeCoeffects
emit(const Func
*, uint32_t, void*, RuntimeCoeffects
) const;
217 jit::SSATmp
* emitJit(jit::irgen::IRGS
&, const Func
*,
218 uint32_t, jit::SSATmp
*, jit::SSATmp
*) const;
220 bool isClosureParentScope() const;
221 bool isGeneratorThis() const;
222 bool isCaller() const;
224 Optional
<std::string
> toString(const Func
*) const;
225 std::string
getDirectiveString() const;
227 bool operator==(const CoeffectRule
&) const;
228 bool operator<(const CoeffectRule
&) const;
232 template<class SerDe
>
247 Type m_type
{Type::Invalid
};
248 bool m_isClass
{false};
250 std::vector
<LowStringPtr
> m_types
{};
251 LowStringPtr m_name
{nullptr};
254 ///////////////////////////////////////////////////////////////////////////////
257 //////////////////////////////////////////////////////////////////////////////
261 //////////////////////////////////////////////////////////////////////////////
264 struct hash
<HPHP::RuntimeCoeffects
> {
265 size_t operator()(HPHP::RuntimeCoeffects c
) const {
271 struct hash
<HPHP::CoeffectRule
> {
272 size_t operator()(const HPHP::CoeffectRule
& r
) const {
277 //////////////////////////////////////////////////////////////////////////////