Emit fatal when unit takes a reference to a local superglobal
[hiphop-php.git] / hphp / hhbbc / interp.h
blobc5b7b41f2f5930f796db360d7f48fc045ceee6da
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 +----------------------------------------------------------------------+
16 #ifndef incl_HHBBC_INTERP_H_
17 #define incl_HHBBC_INTERP_H_
19 #include <functional>
20 #include <vector>
21 #include <bitset>
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;
34 struct CollectedInfo;
35 struct State;
36 struct StepFlags;
37 struct Bytecode;
38 struct ISS;
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
51 * interpreter.
53 struct RunFlags {
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
63 * NoLocalId.
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.
78 struct StepFlags {
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.
89 bool wasPEI = true;
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
102 * constant.
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
120 * this set.
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
148 * NoLocalId.
150 LocalId retParam{NoLocalId};
153 //////////////////////////////////////////////////////////////////////
156 * Context for running the block interpreter (either on a single
157 * instruction, or for a whole block).
159 struct Interp {
160 const Index& index;
161 Context ctx;
162 CollectedInfo& collect;
163 const BlockId bid;
164 const php::Block* blk;
165 State& state;
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,
208 uint32_t numParams,
209 bool unpack);
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 //////////////////////////////////////////////////////////////////////
228 #endif