PageRenderTime 24ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/hphp/compiler/analysis/symbol_table.h

https://bitbucket.org/gnanakeethan/hiphop-php
C Header | 395 lines | 288 code | 48 blank | 59 comment | 4 complexity | c59e51e4ff8aad2d239cbaac83fd4ab4 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception
  1. /*
  2. +----------------------------------------------------------------------+
  3. | HipHop for PHP |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 2010- 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. #ifndef incl_HPHP_SYMBOL_TABLE_H_
  17. #define incl_HPHP_SYMBOL_TABLE_H_
  18. #include "hphp/compiler/hphp.h"
  19. #include "hphp/util/json.h"
  20. #include "hphp/util/util.h"
  21. #include "hphp/util/lock.h"
  22. namespace HPHP {
  23. ///////////////////////////////////////////////////////////////////////////////
  24. class BlockScope;
  25. class CodeGenerator;
  26. class Variant;
  27. DECLARE_BOOST_TYPES(Construct);
  28. DECLARE_BOOST_TYPES(Type);
  29. DECLARE_BOOST_TYPES(AnalysisResult);
  30. DECLARE_BOOST_TYPES(SymbolTable);
  31. DECLARE_BOOST_TYPES(FunctionScope);
  32. DECLARE_BOOST_TYPES(ClassScope);
  33. DECLARE_BOOST_TYPES(FileScope);
  34. DECLARE_BOOST_TYPES(BlockScope);
  35. // used by global_variables.h generation in variable_table.cpp
  36. typedef std::set<std::string> SymbolSet;
  37. typedef std::map<std::string, std::set<std::string> > Type2SymbolSetMap;
  38. class Symbol;
  39. typedef hphp_string_map<Symbol*> StringToSymbolMap;
  40. typedef std::vector<Symbol*> SymbolVec;
  41. class Symbol {
  42. public:
  43. Symbol() : m_hash(0), m_parameter(-1) { m_flags_val = 0; }
  44. void import(BlockScopeRawPtr scope, const Symbol &src_sym);
  45. void beginLocal(BlockScopeRawPtr scope);
  46. void endLocal (BlockScopeRawPtr scope);
  47. void resetLocal(BlockScopeRawPtr scope);
  48. void setName(const std::string &name) {
  49. m_name = name;
  50. m_hash = (unsigned int) hash_string_inline(m_name.c_str(), m_name.size());
  51. }
  52. const std::string &getName() const { return m_name; }
  53. unsigned int getHash() const { return m_hash; }
  54. TypePtr getType() const { return m_coerced; }
  55. TypePtr getFinalType() const;
  56. TypePtr setType(AnalysisResultConstPtr ar, BlockScopeRawPtr scope,
  57. TypePtr type, bool coerced);
  58. bool isPresent() const { return m_flags.m_declaration_set; }
  59. bool checkDefined();
  60. bool declarationSet() const { return m_flags.m_declaration_set; }
  61. bool isReplaced() const { return m_flags.m_replaced; }
  62. void setReplaced() { m_flags.m_replaced = true; }
  63. bool valueSet() const { return m_flags.m_value_set; }
  64. bool isSystem() const { return m_flags.m_system; }
  65. bool isSep() const { return m_flags.m_sep; }
  66. void setSystem() { m_flags.m_system = true; }
  67. void setSep() { m_flags.m_sep = true; }
  68. bool isConstant() const { return m_flags.m_constant; }
  69. void setConstant() { m_flags.m_constant = true; }
  70. ConstructPtr getValue() const { return m_value; }
  71. ConstructPtr getDeclaration() const { return m_declaration; }
  72. void setValue(ConstructPtr value) {
  73. m_flags.m_value_set = true;
  74. m_value = value;
  75. }
  76. void setDeclaration(ConstructPtr declaration) {
  77. m_flags.m_declaration_set = true;
  78. m_declaration = declaration;
  79. }
  80. /* ConstantTable */
  81. bool isDynamic() const { return m_flags.m_dynamic; }
  82. void setDynamic() { m_flags.m_dynamic = true; }
  83. /* VariableTable */
  84. bool isParameter() const { return m_parameter >= 0; }
  85. int getParameterIndex() const { return m_parameter; }
  86. bool isPublic() const { return !isProtected() && !isPrivate(); }
  87. bool isProtected() const { return m_flags.m_protected; }
  88. bool isPrivate() const { return m_flags.m_private; }
  89. bool isStatic() const { return m_flags.m_static; }
  90. bool isGlobal() const { return m_flags.m_global; }
  91. bool isRedeclared() const { return m_flags.m_redeclared; }
  92. bool isLocalGlobal() const { return m_flags.m_localGlobal; }
  93. bool isNestedStatic() const { return m_flags.m_nestedStatic; }
  94. bool isLvalParam() const { return m_flags.m_lvalParam; }
  95. bool isCallTimeRef() const { return m_flags.m_callTimeRef; }
  96. bool isUsed() const { return m_flags.m_used; }
  97. bool isNeeded() const { return m_flags.m_needed; }
  98. bool isSuperGlobal() const { return m_flags.m_superGlobal; }
  99. bool isOverride() const { return m_flags.m_override; }
  100. bool isIndirectAltered() const { return m_flags.m_indirectAltered; }
  101. bool isReferenced() const { return !m_flags.m_notReferenced; }
  102. bool isHidden() const { return m_flags.m_hidden; }
  103. bool isGeneratorParameter() const { return m_flags.m_generatorParameter; }
  104. bool isRefGeneratorParameter() const { return m_flags.m_refGeneratorParameter; }
  105. bool isClosureVar() const { return m_flags.m_closureVar; }
  106. bool isRefClosureVar() const { return m_flags.m_refClosureVar; }
  107. bool isPassClosureVar() const { return m_flags.m_passClosureVar; }
  108. bool isClassName() const { return m_flags.m_className; }
  109. bool isShrinkWrapped() const { return m_flags.m_shrinkWrapped; }
  110. bool isStashedVal() const { return m_flags.m_stashedVal; }
  111. bool isReseated() const { return m_flags. m_reseated; }
  112. void setParameterIndex(int ix) { m_parameter = ix; }
  113. void setProtected() { m_flags.m_protected = true; }
  114. void setPrivate() { m_flags.m_private = true; }
  115. void setStatic() { m_flags.m_static = true; }
  116. void setGlobal() { m_flags.m_global = true; }
  117. void setRedeclared() { m_flags.m_redeclared = true; }
  118. void setLocalGlobal() { m_flags.m_localGlobal = true; }
  119. void setNestedStatic() { m_flags.m_nestedStatic = true; }
  120. void setLvalParam() { m_flags.m_lvalParam = true; }
  121. void setCallTimeRef() { m_flags.m_callTimeRef = true; }
  122. void setUsed() { m_flags.m_used = true; }
  123. void setNeeded() { m_flags.m_needed = true; }
  124. void setSuperGlobal() { m_flags.m_superGlobal = true; }
  125. void setOverride() { m_flags.m_override = true; }
  126. void setIndirectAltered() { m_flags.m_indirectAltered = true; }
  127. void setReferenced() { m_flags.m_notReferenced = false; }
  128. void setHidden() { m_flags.m_hidden = true; }
  129. void setGeneratorParameter() { m_flags.m_generatorParameter = true; }
  130. void setRefGeneratorParameter() { m_flags.m_refGeneratorParameter = true; }
  131. void setClosureVar() { m_flags.m_closureVar = true; }
  132. void setRefClosureVar() { m_flags.m_refClosureVar = true; }
  133. void setPassClosureVar() { m_flags.m_passClosureVar = true; }
  134. void setClassName() { m_flags.m_className = true; }
  135. void setShrinkWrapped() { m_flags.m_shrinkWrapped = true; }
  136. void setStashedVal() { m_flags.m_stashedVal = true; }
  137. void setReseated() { m_flags.m_reseated = true; }
  138. void clearGlobal() { m_flags.m_global = false; }
  139. void clearUsed() { m_flags.m_used = false; }
  140. void clearNeeded() { m_flags.m_needed = false; }
  141. void clearReferenced() { m_flags.m_notReferenced = true; }
  142. void clearReseated() { m_flags.m_reseated = false; }
  143. void clearRefClosureVar() { m_flags.m_refClosureVar = false; }
  144. void update(Symbol *src) {
  145. m_flags_val = src->m_flags_val;
  146. }
  147. ConstructPtr getStaticInitVal() const {
  148. return m_flags.m_hasStaticInit ? m_initVal : ConstructPtr();
  149. }
  150. ConstructPtr getClassInitVal() const {
  151. return m_flags.m_hasClassInit ? m_initVal : ConstructPtr();
  152. }
  153. void setStaticInitVal(ConstructPtr initVal) {
  154. if (m_flags.m_hasClassInit) initVal.reset();
  155. m_flags.m_hasStaticInit = true;
  156. m_initVal = initVal;
  157. }
  158. void setClassInitVal(ConstructPtr initVal) {
  159. if (m_flags.m_hasStaticInit) initVal.reset();
  160. m_flags.m_hasClassInit = true;
  161. m_initVal = initVal;
  162. }
  163. // we avoid implementing ISerialize for Symbols, since we don't
  164. // want Symbols to need a vtable. Instead, we use the
  165. // wrappers below
  166. void serializeParam(JSON::DocTarget::OutputStream &out) const;
  167. void serializeClassVar(JSON::DocTarget::OutputStream &out) const;
  168. private:
  169. std::string m_name;
  170. unsigned int m_hash;
  171. union {
  172. uint64_t m_flags_val;
  173. struct {
  174. /* internal */
  175. unsigned m_declaration_set : 1;
  176. unsigned m_value_set : 1;
  177. unsigned m_hasStaticInit : 1;
  178. unsigned m_hasClassInit : 1;
  179. unsigned m_constant : 1;
  180. /* common */
  181. unsigned m_system : 1;
  182. unsigned m_sep : 1;
  183. /* ConstantTable */
  184. unsigned m_dynamic : 1;
  185. unsigned m_replaced : 1;
  186. /* VariableTable */
  187. unsigned m_protected : 1;
  188. unsigned m_private : 1;
  189. unsigned m_static : 1;
  190. unsigned m_global : 1;
  191. unsigned m_redeclared : 1;
  192. unsigned m_localGlobal : 1;
  193. unsigned m_nestedStatic : 1;
  194. unsigned m_lvalParam : 1;
  195. unsigned m_callTimeRef : 1;
  196. unsigned m_used : 1;
  197. unsigned m_needed : 1;
  198. unsigned m_superGlobal : 1;
  199. unsigned m_override : 1;
  200. unsigned m_indirectAltered : 1;
  201. unsigned m_notReferenced : 1;
  202. unsigned m_hidden : 1;
  203. unsigned m_generatorParameter : 1;
  204. unsigned m_refGeneratorParameter : 1;
  205. unsigned m_closureVar : 1;
  206. unsigned m_refClosureVar : 1;
  207. unsigned m_passClosureVar : 1;
  208. unsigned m_className : 1;
  209. unsigned m_shrinkWrapped : 1;
  210. unsigned m_stashedVal : 1;
  211. unsigned m_reseated : 1;
  212. } m_flags;
  213. static_assert(
  214. sizeof(m_flags_val) == sizeof(m_flags),
  215. "m_flags_val must cover all the flags");
  216. };
  217. ConstructPtr m_declaration;
  218. ConstructPtr m_value;
  219. TypePtr m_coerced;
  220. TypePtr m_prevCoerced;
  221. int m_parameter;
  222. ConstructPtr m_initVal;
  223. void triggerUpdates(BlockScopeRawPtr scope) const;
  224. static TypePtr CoerceTo(AnalysisResultConstPtr ar,
  225. TypePtr &curType, TypePtr type);
  226. };
  227. class SymParamWrapper : public JSON::DocTarget::ISerializable {
  228. public:
  229. explicit SymParamWrapper(const Symbol* sym) : m_sym(sym) {
  230. assert(sym);
  231. }
  232. virtual void serialize(JSON::DocTarget::OutputStream &out) const {
  233. m_sym->serializeParam(out);
  234. }
  235. private:
  236. const Symbol *m_sym;
  237. };
  238. class SymClassVarWrapper : public JSON::DocTarget::ISerializable {
  239. public:
  240. explicit SymClassVarWrapper(const Symbol* sym) : m_sym(sym) {
  241. assert(sym);
  242. }
  243. virtual void serialize(JSON::DocTarget::OutputStream &out) const {
  244. m_sym->serializeClassVar(out);
  245. }
  246. private:
  247. const Symbol *m_sym;
  248. };
  249. /**
  250. * Base class of VariableTable and ConstantTable.
  251. */
  252. class SymbolTable : public boost::enable_shared_from_this<SymbolTable>,
  253. public JSON::CodeError::ISerializable {
  254. public:
  255. static Mutex AllSymbolTablesMutex;
  256. static SymbolTablePtrList AllSymbolTables; // for stats purpose
  257. static void Purge();
  258. static void CountTypes(std::map<std::string, int> &counts);
  259. BlockScope *getScopePtr() const { return &m_blockScope; }
  260. BlockScopeRawPtr getBlockScope() const {
  261. return BlockScopeRawPtr(&m_blockScope);
  262. }
  263. public:
  264. SymbolTable(BlockScope &blockScope, bool isConst);
  265. SymbolTable();
  266. virtual ~SymbolTable();
  267. void beginLocal();
  268. void endLocal();
  269. void resetLocal();
  270. /**
  271. * Import system symbols into this.
  272. */
  273. void import(SymbolTablePtr src);
  274. /**
  275. * Whether it's declared.
  276. */
  277. bool isPresent(const std::string &name) const;
  278. /**
  279. * Whether a symbol is defined.
  280. */
  281. bool checkDefined(const std::string &name);
  282. /**
  283. * Whether a symbol is a system symbol.
  284. */
  285. bool isSystem(const std::string &name) const;
  286. /**
  287. * Whether or not this is inherited from a parent scope. For examples,
  288. * properties from base classes or a global variable.
  289. */
  290. virtual bool isInherited(const std::string &name) const {
  291. return isSystem(name);
  292. }
  293. /**
  294. * Implements JSON::CodeError::ISerializable.
  295. */
  296. virtual void serialize(JSON::CodeError::OutputStream &out) const;
  297. /**
  298. * Find a symbol's inferred type.
  299. */
  300. TypePtr getType(const std::string &name) const;
  301. TypePtr getFinalType(const std::string &name) const;
  302. /**
  303. * Find declaration construct.
  304. */
  305. bool isExplicitlyDeclared(const std::string &name) const;
  306. ConstructPtr getDeclaration(const std::string &name) const;
  307. ConstructPtr getValue(const std::string &name) const;
  308. /* Whether this constant is brought in by a separable extension */
  309. void setSepExtension(const std::string &name);
  310. bool isSepExtension(const std::string &name) const;
  311. /**
  312. * How big of a hash table for generate C++ switch statements.
  313. */
  314. int getJumpTableSize() const {
  315. return Util::roundUpToPowerOfTwo(m_symbolVec.size() * 2);
  316. }
  317. void canonicalizeSymbolOrder();
  318. void getSymbols(std::vector<Symbol*> &syms, bool filterHidden = false) const;
  319. void getSymbols(std::vector<std::string> &syms) const;
  320. const std::vector<Symbol*> &getSymbols() const { return m_symbolVec; }
  321. void getCoerced(StringToTypePtrMap &coerced) const;
  322. virtual TypePtr setType(AnalysisResultConstPtr ar, const std::string &name,
  323. TypePtr type, bool coerced);
  324. virtual TypePtr setType(AnalysisResultConstPtr ar, Symbol *sym,
  325. TypePtr type, bool coerced);
  326. Symbol *getSymbol(const std::string &name);
  327. const Symbol *getSymbol(const std::string &name) const;
  328. FunctionScopeRawPtr getFunctionScope();
  329. ClassScopeRawPtr getClassScope();
  330. FileScopeRawPtr getFileScope();
  331. static std::string getEscapedText(Variant v, int &len);
  332. protected:
  333. Symbol *genSymbol(const std::string &name, bool konst);
  334. Symbol *genSymbol(const std::string &name, bool konst,
  335. ConstructPtr construct);
  336. typedef std::map<std::string,Symbol> StringToSymbolMap;
  337. BlockScope &m_blockScope; // owner
  338. std::vector<Symbol*> m_symbolVec; // in declaration order
  339. StringToSymbolMap m_symbolMap;
  340. void countTypes(std::map<std::string, int> &counts);
  341. private:
  342. const Symbol* getSymbolImpl(const std::string &name) const;
  343. bool m_const;
  344. };
  345. ///////////////////////////////////////////////////////////////////////////////
  346. }
  347. #endif // incl_HPHP_SYMBOL_TABLE_H_