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 +----------------------------------------------------------------------+
16 #ifndef incl_HHBBC_INTERP_H_
17 #define incl_HHBBC_INTERP_H_
23 #include <folly/Optional.h>
25 #include "hphp/hhbbc/bc.h"
26 #include "hphp/hhbbc/context.h"
27 #include "hphp/hhbbc/index.h"
28 #include "hphp/hhbbc/misc.h"
29 #include "hphp/hhbbc/type-system.h"
31 namespace HPHP
{ namespace HHBBC
{
33 struct PropertiesInfo
;
39 namespace php
{ struct Block
; }
40 namespace res
{ struct Func
; }
42 //////////////////////////////////////////////////////////////////////
44 constexpr auto kReadOnlyConstant
= kInvalidDataType
;
45 constexpr auto kDynamicConstant
= kExtraInvalidDataType
;
47 //////////////////////////////////////////////////////////////////////
50 * RunFlags are information about running an entire block in the
55 * If this is not none, the interpreter executed a return in this
56 * block, with this type.
58 folly::Optional
<Type
> returned
;
61 * If returned is set, and the returned value was a parameter,
62 * retParam will be set to the parameter's id; otherwise it will be
65 LocalId retParam
{NoLocalId
};
68 //////////////////////////////////////////////////////////////////////
70 constexpr int kMaxTrackedLocals
= 512;
71 constexpr int kMaxTrackedClsRefSlots
= 64;
74 * StepFlags are information about the effects of a single opcode.
75 * Each single-instruction step of the interpreter sends various
76 * effects information back to the caller in this structure.
80 * Potentially Exception-throwing Instruction.
82 * Instructions are assumed to be PEIs unless the abstract
83 * interpreter says they aren't. A PEI must propagate the state
84 * from before the instruction across all throw exit edges.
86 * Some instructions that can throw with mid-opcode states need to
87 * handle those cases specially.
92 * If set to something other than NoBlockId, then this block
93 * unconditionally falls through to that block.
95 BlockId jmpDest
= NoBlockId
;
98 * If an instruction sets this flag, it means that if it pushed a
99 * type with a constant value, it had no side effects other than
100 * computing the value which was pushed. This means the instruction
101 * can be replaced with pops of its inputs followed by a push of the
104 bool canConstProp
= false;
107 * If an instruction sets this flag, it means that this
108 * instruction doesn't prevent a call to the containing function
109 * from being discarded if its result is unneeded.
111 * Instructions that are marked canConstProp that also produce a
112 * constant result automatically set this flag.
114 bool effectFree
= false;
117 * If an instruction may read or write to locals, these flags
118 * indicate which ones. We don't track this information for local
119 * ids past kMaxTrackedLocals, which are assumed to always be in
122 * This is currently used to try to leave out unnecessary type
123 * assertions on locals (for options.FilterAssertions), and as a
124 * conservative list of variables that should be added to the gen
125 * set for global dce.
127 * The latter use means these flags must be conservative in the
128 * direction of which locals are read. That is: an instruction may
129 * not read a local that isn't mentioned in this set.
131 std::bitset
<kMaxTrackedLocals
> mayReadLocalSet
;
134 * If the instruction on this step could've been replaced with
135 * cheaper bytecode, this is the list of bytecode that can be used.
137 folly::Optional
<BytecodeVec
> strengthReduced
;
140 * If this is not none, the interpreter executed a return on this
141 * step, with this type.
143 folly::Optional
<Type
> returned
;
146 * If returned is set, and the returned value was a parameter,
147 * retParam will be set to the parameter's id; otherwise it will be
150 LocalId retParam
{NoLocalId
};
153 //////////////////////////////////////////////////////////////////////
156 * Context for running the block interpreter (either on a single
157 * instruction, or for a whole block).
162 CollectedInfo
& collect
;
164 const php::Block
* blk
;
169 * Step a single instruction in the block, and hand back flags
171 * This entry point is used to propagate block entry states to
172 * mid-block positions after the global analysis has already finished.
174 StepFlags
step(Interp
&, const Bytecode
& op
);
177 * Run a whole block. Returns a type that should be merged into the
178 * function return value, or TBottom.
180 * If a branch is taken or an exception is thrown, the supplied
181 * callback is used to indicate when/where the state referenced in the
182 * Interp structure should be propagated.
184 * If the PropagateFn is called with a nullptr State, it means that
185 * the given block should be re-processed.
187 using PropagateFn
= std::function
<void (BlockId
, const State
*)>;
188 RunFlags
run(Interp
&, PropagateFn
);
191 * Dispatch a bytecode to the default interpreter.
193 * This entry point is used by custom interpreters that need to add
194 * some logic to the default interpreter but want to run it otherwise.
195 * Calling step() does not give control over the state (ISS instance)
196 * which a custom interpreter may need to specialize.
198 void default_dispatch(ISS
&, const Bytecode
&);
201 * Can this call be converted to an FCallBuiltin
203 bool can_emit_builtin(const php::Func
* func
,
204 int numParams
, bool hasUnpack
);
206 void finish_builtin(ISS
& env
,
207 const php::Func
* func
,
211 bool handle_function_exists(ISS
& env
, int numArgs
, bool allowConstProp
);
213 folly::Optional
<Type
>
214 const_fold(ISS
& env
, uint32_t nArgs
, const res::Func
& rfunc
);
216 folly::Optional
<Type
> thisType(const Index
& index
, Context ctx
);
219 * Extracts name from the type either by using a reified name specialization or
220 * by looking at the typed value
222 SString
getNameFromType(const Type
& t
);
224 //////////////////////////////////////////////////////////////////////