PageRenderTime 33ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/hphp/runtime/vm/func-emitter.h

https://github.com/soitun/hiphop-php
C Header | 420 lines | 165 code | 83 blank | 172 comment | 0 complexity | b1510f89e16a42e0e2616344859ee42e MD5 | raw file
  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. +----------------------------------------------------------------------+
  15. */
  16. #pragma once
  17. #include "hphp/runtime/base/attr.h"
  18. #include "hphp/runtime/base/datatype.h"
  19. #include "hphp/runtime/base/type-string.h"
  20. #include "hphp/runtime/base/typed-value.h"
  21. #include "hphp/runtime/base/user-attributes.h"
  22. #include "hphp/runtime/vm/func.h"
  23. #include "hphp/runtime/vm/type-constraint.h"
  24. #include "hphp/runtime/vm/unit.h"
  25. #include "hphp/runtime/vm/unit-emitter.h"
  26. #include <utility>
  27. #include <vector>
  28. namespace HPHP {
  29. ///////////////////////////////////////////////////////////////////////////////
  30. struct PreClass;
  31. struct StringData;
  32. struct PreClassEmitter;
  33. struct BlobDecoder;
  34. namespace Native {
  35. struct NativeFunctionInfo;
  36. }
  37. ///////////////////////////////////////////////////////////////////////////////
  38. /*
  39. * Bag of Func's fields used to emit Funcs.
  40. */
  41. struct FuncEmitter {
  42. /////////////////////////////////////////////////////////////////////////////
  43. // Types.
  44. using UpperBoundVec = CompactVector<TypeConstraint>;
  45. using UpperBoundMap =
  46. std::unordered_map<const StringData*, CompactVector<TypeConstraint>>;
  47. struct ParamInfo : public Func::ParamInfo {
  48. ParamInfo() {}
  49. template<class SerDe>
  50. void serde(SerDe& sd) {
  51. Func::ParamInfo* parent = this;
  52. parent->serde(sd);
  53. sd(upperBounds);
  54. }
  55. UpperBoundVec upperBounds;
  56. };
  57. typedef std::vector<ParamInfo> ParamInfoVec;
  58. typedef std::vector<EHEnt> EHEntVec;
  59. using CoeffectRuleVec = std::vector<CoeffectRule>;
  60. using StaticCoeffectsVec = std::vector<LowStringPtr>;
  61. /////////////////////////////////////////////////////////////////////////////
  62. // Initialization and execution.
  63. FuncEmitter(UnitEmitter& ue, int sn, Id id, const StringData* n);
  64. FuncEmitter(UnitEmitter& ue, int sn, const StringData* n,
  65. PreClassEmitter* pce);
  66. ~FuncEmitter();
  67. /*
  68. * Just set some fields when we start and stop emitting.
  69. */
  70. void init(int l1, int l2, Attr attrs_,
  71. const StringData* docComment_);
  72. void finish();
  73. /*
  74. * Instantiate a runtime Func*.
  75. */
  76. Func* create(Unit& unit, PreClass* preClass = nullptr) const;
  77. /////////////////////////////////////////////////////////////////////////////
  78. // Serialization.
  79. /////////////////////////////////////////////////////////////////////////////
  80. // Serialization.
  81. template<class SerDe> void serdeMetaData(SerDe&);
  82. template<class SerDe> void serde(SerDe&, bool lazy);
  83. // Deserializing just a LineTable, previously encoded by serde (the
  84. // BlobDecoder must be at the correct offset).
  85. static void deserializeLineTable(BlobDecoder&, LineTable&);
  86. // Load a line table out of the unit given by the SN at the given
  87. // token. The token is the offset of the line table within the unit.
  88. static LineTable loadLineTableFromRepo(int64_t, RepoFile::Token);
  89. /////////////////////////////////////////////////////////////////////////////
  90. // Metadata.
  91. /*
  92. * Get the associated Unit and PreClass emitters.
  93. */
  94. UnitEmitter& ue() const;
  95. PreClassEmitter* pce() const;
  96. /*
  97. * XXX: What are these for?
  98. */
  99. int sn() const;
  100. Id id() const;
  101. /////////////////////////////////////////////////////////////////////////////
  102. // Locals, iterators, and parameters.
  103. /*
  104. * Count things.
  105. */
  106. Id numLocals() const;
  107. Id numNamedLocals() const;
  108. Id numIterators() const;
  109. Id numLiveIterators() const;
  110. /*
  111. * Set things.
  112. */
  113. void setNumIterators(Id numIterators);
  114. void setNumLiveIterators(Id id);
  115. /*
  116. * Check existence of, look up, and allocate named locals.
  117. */
  118. bool hasVar(const StringData* name) const;
  119. Id lookupVarId(const StringData* name) const;
  120. void allocVarId(const StringData* name, bool slotless = false);
  121. /*
  122. * Allocate unnamed locals.
  123. */
  124. Id allocUnnamedLocal();
  125. /*
  126. * Allocate and free iterators.
  127. */
  128. Id allocIterator();
  129. void freeIterator(Id id);
  130. /*
  131. * Add a parameter and corresponding named local.
  132. */
  133. void appendParam(const StringData* name, const ParamInfo& info);
  134. /*
  135. * Get the local variable name -> id map.
  136. */
  137. const Func::NamedLocalsMap::Builder& localNameMap() const;
  138. /////////////////////////////////////////////////////////////////////////////
  139. // Unit tables.
  140. /*
  141. * Add entries to the EH table, and return them by reference.
  142. */
  143. EHEnt& addEHEnt();
  144. private:
  145. /*
  146. * Private table sort routines; called at finish()-time.
  147. */
  148. void sortEHTab();
  149. public:
  150. /*
  151. * Declare that the EH table was created in sort-order and doesn't need to be
  152. * resorted at finish() time.
  153. */
  154. void setEHTabIsSorted();
  155. /////////////////////////////////////////////////////////////////////////////
  156. // Helper accessors. [const]
  157. /*
  158. * Is the function a method, variadic (i.e., takes a `...'
  159. * parameter), or an HNI function with a native implementation?
  160. */
  161. bool isMethod() const;
  162. bool isVariadic() const;
  163. /*
  164. * @returns: std::make_pair(line1, line2)
  165. */
  166. std::pair<int,int> getLocation() const;
  167. Native::NativeFunctionInfo getNativeInfo() const;
  168. String nativeFullname() const;
  169. /////////////////////////////////////////////////////////////////////////////
  170. // Complex setters.
  171. //
  172. /*
  173. * Shorthand for setting `line1' and `line2' because typing is hard.
  174. */
  175. void setLocation(int l1, int l2);
  176. /*
  177. * Pulls native and system attributes out of the user attributes map.
  178. *
  179. * System attributes are returned by reference through `attrs_', and native
  180. * attributes are returned as an integer.
  181. */
  182. int parseNativeAttributes(Attr& attrs_) const;
  183. /*
  184. * Fix some attributes based on the current runtime options that may
  185. * have been stored incorrectly in the repo.
  186. */
  187. Attr fix_attrs(Attr a) const;
  188. /////////////////////////////////////////////////////////////////////////////
  189. // Bytecode.
  190. Offset offsetOf(const unsigned char* pc) const;
  191. /*
  192. * Bytecode pointer and current emit position.
  193. */
  194. const unsigned char* bc() const;
  195. Offset bcPos() const;
  196. /*
  197. * Set the bytecode pointer by allocating a copy of `bc' with size `bclen'.
  198. *
  199. * Not safe to call with m_bc as the argument because we free our current
  200. * bytecode stream before allocating a copy of `bc'.
  201. */
  202. void setBc(const unsigned char* bc, size_t bclen);
  203. void setBcToken(Func::BCPtr::Token token, size_t bclen);
  204. Optional<Func::BCPtr::Token> loadBc();
  205. /////////////////////////////////////////////////////////////////////////////
  206. // Bytecode emit.
  207. //
  208. // These methods emit values to bc() at bcPos() (or pos, if given) and then
  209. // update bcPos(), realloc-ing the bytecode region if necessary.
  210. void emitOp(Op op);
  211. void emitByte(unsigned char n, int64_t pos = -1);
  212. void emitInt16(uint16_t n, int64_t pos = -1);
  213. void emitInt32(int n, int64_t pos = -1);
  214. void emitInt64(int64_t n, int64_t pos = -1);
  215. void emitDouble(double n, int64_t pos = -1);
  216. void emitIVA(bool) = delete;
  217. template<typename T> void emitIVA(T n);
  218. void emitNamedLocal(NamedLocal loc);
  219. private:
  220. /*
  221. * Bytecode emit implementation.
  222. */
  223. template<class T>
  224. void emitImpl(T n, int64_t pos);
  225. /////////////////////////////////////////////////////////////////////////////
  226. // Source locations.
  227. public:
  228. /*
  229. * Return a copy of the SrcLocTable for the Func, if it has one; otherwise,
  230. * return an empty table.
  231. */
  232. SourceLocTable createSourceLocTable() const;
  233. /*
  234. * Does this Func contain full source location information?
  235. *
  236. * Generally, FuncEmitters loaded from a production repo will have a
  237. * LineTable only instead of a full SourceLocTable.
  238. */
  239. bool hasSourceLocInfo() const;
  240. /*
  241. * Const reference to the Func's LineTable.
  242. */
  243. const LineTable& lineTable() const;
  244. /*
  245. * Record source location information for the last chunk of bytecode added to
  246. * this FuncEmitter.
  247. *
  248. * Adjacent regions associated with the same source line will be collapsed as
  249. * this is created.
  250. */
  251. void recordSourceLocation(const Location::Range& sLoc, Offset start);
  252. /////////////////////////////////////////////////////////////////////////////
  253. // Data members.
  254. private:
  255. // Initial bytecode size.
  256. static const size_t BCMaxInit = 64;
  257. /*
  258. * Metadata.
  259. */
  260. UnitEmitter& m_ue;
  261. PreClassEmitter* m_pce;
  262. int m_sn;
  263. Id m_id;
  264. Func::BCPtr m_bc;
  265. size_t m_bclen;
  266. size_t m_bcmax;
  267. public:
  268. /*
  269. * Func fields.
  270. */
  271. int line1;
  272. int line2;
  273. LowStringPtr name;
  274. Attr attrs;
  275. ParamInfoVec params;
  276. int16_t maxStackCells{0};
  277. MaybeDataType hniReturnType;
  278. TypeConstraint retTypeConstraint;
  279. LowStringPtr retUserType;
  280. UpperBoundVec retUpperBounds;
  281. StaticCoeffectsVec staticCoeffects;
  282. CoeffectRuleVec coeffectRules;
  283. EHEntVec ehtab;
  284. union {
  285. uint16_t m_repoBoolBitset{0};
  286. struct {
  287. bool isMemoizeWrapper : 1;
  288. bool isMemoizeWrapperLSB : 1;
  289. bool isClosureBody : 1;
  290. bool isAsync : 1;
  291. bool containsCalls : 1;
  292. bool isNative : 1;
  293. bool isGenerator : 1;
  294. bool isPairGenerator : 1;
  295. bool hasParamsWithMultiUBs : 1;
  296. bool hasReturnWithMultiUBs : 1;
  297. };
  298. };
  299. LowStringPtr docComment;
  300. LowStringPtr originalFilename;
  301. UserAttributeMap userAttributes;
  302. StringData* memoizePropName;
  303. StringData* memoizeGuardPropName;
  304. int memoizeSharedPropIndex;
  305. RepoAuthType repoReturnType;
  306. RepoAuthType repoAwaitedReturnType;
  307. private:
  308. /*
  309. * FuncEmitter-managed state.
  310. */
  311. Func::NamedLocalsMap::Builder m_localNames;
  312. Id m_numLocals;
  313. int m_numUnnamedLocals;
  314. Id m_numIterators;
  315. Id m_nextFreeIterator;
  316. bool m_ehTabSorted : 1;
  317. /*
  318. * Source location tables.
  319. *
  320. * Each entry encodes an open-closed range of bytecode offsets.
  321. *
  322. * The m_sourceLocTab is keyed by the start of each half-open range. This is
  323. * to allow appending new bytecode offsets that are part of the same range to
  324. * coalesce.
  325. *
  326. * The m_lineTable is keyed by the past-the-end offset. This is the
  327. * format we'll want it in when we go to create a Unit.
  328. */
  329. void setLineTable(LineTable);
  330. std::vector<std::pair<Offset,SourceLoc>> m_sourceLocTab;
  331. Func::LineTablePtr m_lineTable;
  332. };
  333. ///////////////////////////////////////////////////////////////////////////////
  334. }
  335. #define incl_HPHP_VM_FUNC_EMITTER_INL_H_
  336. #include "hphp/runtime/vm/func-emitter-inl.h"
  337. #undef incl_HPHP_VM_FUNC_EMITTER_INL_H_