ScopeInfo.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. namespace Js {
  7. class ByteCodeBufferBuilder;
  8. class ByteCodeBufferReader;
  9. //
  10. // ScopeInfo is used to persist Scope info of outer functions. When reparsing deferred nested
  11. // functions, use persisted ScopeInfo to restore outer closures.
  12. //
  13. class ScopeInfo
  14. {
  15. friend class ByteCodeBufferBuilder;
  16. friend class ByteCodeBufferReader;
  17. DECLARE_RECYCLER_VERIFY_MARK_FRIEND()
  18. struct MapSymbolData
  19. {
  20. ByteCodeGenerator *byteCodeGenerator;
  21. FuncInfo* func;
  22. int nonScopeSymbolCount;
  23. };
  24. struct SymbolInfo
  25. {
  26. union
  27. {
  28. Field(PropertyId) propertyId;
  29. Field(PropertyRecord const*) name;
  30. };
  31. Field(SymbolType) symbolType;
  32. Field(bool) hasFuncAssignment : 1;
  33. Field(bool) isBlockVariable : 1;
  34. Field(bool) isConst : 1;
  35. Field(bool) isFuncExpr : 1;
  36. Field(bool) isModuleExportStorage : 1;
  37. Field(bool) isModuleImport : 1;
  38. };
  39. private:
  40. Field(ScopeInfo *) parent; // link to parent scope info (if any)
  41. Field(FunctionInfo * const) functionInfo;// link to function owning this scope
  42. Field(BYTE) isDynamic : 1; // isDynamic bit affects how deferredChild access global ref
  43. Field(BYTE) isObject : 1; // isObject bit affects how deferredChild access closure symbols
  44. Field(BYTE) mustInstantiate : 1; // the scope must be instantiated as an object/array
  45. Field(BYTE) isCached : 1; // indicates that local vars and functions are cached across invocations
  46. Field(BYTE) areNamesCached : 1;
  47. Field(BYTE) hasLocalInClosure : 1;
  48. Field(BYTE) isGeneratorFunctionBody : 1;
  49. Field(BYTE) isAsyncFunctionBody : 1;
  50. FieldNoBarrier(Scope *) scope;
  51. Field(::ScopeType) scopeType;
  52. Field(int) scopeId;
  53. Field(int) symbolCount; // symbol count in this scope
  54. Field(SymbolInfo) symbols[]; // symbol PropertyIDs, index == sym.scopeSlot
  55. private:
  56. ScopeInfo(FunctionInfo * function, int symbolCount)
  57. : functionInfo(function), /*funcExprScopeInfo(nullptr), paramScopeInfo(nullptr),*/ symbolCount(symbolCount), parent(nullptr), scope(nullptr), areNamesCached(false), hasLocalInClosure(false), isGeneratorFunctionBody(false), isAsyncFunctionBody(false)/*, parentOnly(false)*/
  58. {
  59. }
  60. void SetSymbolId(int i, PropertyId propertyId)
  61. {
  62. Assert(!areNamesCached);
  63. Assert(i >= 0 && i < symbolCount);
  64. symbols[i].propertyId = propertyId;
  65. }
  66. void SetSymbolType(int i, SymbolType symbolType)
  67. {
  68. Assert(!areNamesCached);
  69. Assert(i >= 0 && i < symbolCount);
  70. symbols[i].symbolType = symbolType;
  71. }
  72. void SetHasFuncAssignment(int i, bool has)
  73. {
  74. Assert(!areNamesCached);
  75. Assert(i >= 0 && i < symbolCount);
  76. symbols[i].hasFuncAssignment = has;
  77. }
  78. void SetIsBlockVariable(int i, bool is)
  79. {
  80. Assert(!areNamesCached);
  81. Assert(i >= 0 && i < symbolCount);
  82. symbols[i].isBlockVariable = is;
  83. }
  84. void SetIsConst(int i, bool is)
  85. {
  86. Assert(!areNamesCached);
  87. Assert(i >= 0 && i < symbolCount);
  88. symbols[i].isConst = is;
  89. }
  90. void SetIsFuncExpr(int i, bool is)
  91. {
  92. Assert(!areNamesCached);
  93. Assert(i >= 0 && i < symbolCount);
  94. symbols[i].isFuncExpr = is;
  95. }
  96. void SetIsModuleExportStorage(int i, bool is)
  97. {
  98. Assert(!areNamesCached);
  99. Assert(i >= 0 && i < symbolCount);
  100. symbols[i].isModuleExportStorage = is;
  101. }
  102. void SetIsModuleImport(int i, bool is)
  103. {
  104. Assert(!areNamesCached);
  105. Assert(i >= 0 && i < symbolCount);
  106. symbols[i].isModuleImport = is;
  107. }
  108. void SetPropertyName(int i, PropertyRecord const* name)
  109. {
  110. Assert(!areNamesCached);
  111. Assert(i >= 0 && i < symbolCount);
  112. symbols[i].name = name;
  113. }
  114. PropertyId GetSymbolId(int i) const
  115. {
  116. Assert(!areNamesCached);
  117. Assert(i >= 0 && i < symbolCount);
  118. return symbols[i].propertyId;
  119. }
  120. SymbolType GetSymbolType(int i) const
  121. {
  122. Assert(i >= 0 && i < symbolCount);
  123. return symbols[i].symbolType;
  124. }
  125. bool GetHasFuncAssignment(int i)
  126. {
  127. Assert(i >= 0 && i < symbolCount);
  128. return symbols[i].hasFuncAssignment;
  129. }
  130. bool GetIsModuleExportStorage(int i)
  131. {
  132. Assert(i >= 0 && i < symbolCount);
  133. return symbols[i].isModuleExportStorage;
  134. }
  135. bool GetIsModuleImport(int i)
  136. {
  137. Assert(i >= 0 && i < symbolCount);
  138. return symbols[i].isModuleImport;
  139. }
  140. bool GetIsBlockVariable(int i)
  141. {
  142. Assert(i >= 0 && i < symbolCount);
  143. return symbols[i].isBlockVariable;
  144. }
  145. bool GetIsConst(int i)
  146. {
  147. Assert(i >= 0 && i < symbolCount);
  148. return symbols[i].isConst;
  149. }
  150. bool GetIsFuncExpr(int i)
  151. {
  152. Assert(i >= 0 && i < symbolCount);
  153. return symbols[i].isFuncExpr;
  154. }
  155. PropertyRecord const* GetPropertyName(int i)
  156. {
  157. Assert(areNamesCached);
  158. Assert(i >= 0 && i < symbolCount);
  159. return symbols[i].name;
  160. }
  161. void SaveSymbolInfo(Symbol* sym, MapSymbolData* mapSymbolData);
  162. static ScopeInfo* SaveScopeInfo(ByteCodeGenerator * byteCodeGenerator, Scope * scope, ScriptContext * scriptContext);
  163. static ScopeInfo* SaveOneScopeInfo(ByteCodeGenerator * byteCodeGenerator, Scope * scope, ScriptContext * scriptContext);
  164. public:
  165. FunctionInfo * GetFunctionInfo() const
  166. {
  167. return functionInfo;
  168. }
  169. ParseableFunctionInfo * GetParseableFunctionInfo() const
  170. {
  171. return functionInfo ? functionInfo->GetParseableFunctionInfo() : nullptr;
  172. }
  173. ScopeInfo* GetParentScopeInfo() const
  174. {
  175. return parent;//? parent->GetParseableFunctionInfo()->GetScopeInfo() : nullptr;
  176. }
  177. void SetParentScopeInfo(ScopeInfo * parent)
  178. {
  179. Assert(this->parent == nullptr);
  180. this->parent = parent;
  181. }
  182. Scope * GetScope() const
  183. {
  184. return scope;
  185. }
  186. void SetScope(Scope * scope)
  187. {
  188. this->scope = scope;
  189. }
  190. ::ScopeType GetScopeType() const
  191. {
  192. return scopeType;
  193. }
  194. void SetScopeType(::ScopeType type)
  195. {
  196. this->scopeType = type;
  197. }
  198. void SetScopeId(int id)
  199. {
  200. this->scopeId = id;
  201. }
  202. int GetScopeId() const
  203. {
  204. return scopeId;
  205. }
  206. int GetSymbolCount() const
  207. {
  208. return symbolCount;
  209. }
  210. bool IsObject() const
  211. {
  212. return isObject;
  213. }
  214. bool IsCached() const
  215. {
  216. return isCached;
  217. }
  218. void SetHasLocalInClosure(bool has)
  219. {
  220. hasLocalInClosure = has;
  221. }
  222. bool GetHasOwnLocalInClosure() const
  223. {
  224. return hasLocalInClosure;
  225. }
  226. bool IsGeneratorFunctionBody() const
  227. {
  228. return this->isGeneratorFunctionBody;
  229. }
  230. bool IsAsyncFunctionBody() const
  231. {
  232. return this->isAsyncFunctionBody;
  233. }
  234. static void SaveEnclosingScopeInfo(ByteCodeGenerator* byteCodeGenerator, /*FuncInfo* parentFunc,*/ FuncInfo* func);
  235. void EnsurePidTracking(ScriptContext* scriptContext);
  236. void ExtractScopeInfo(Parser *parser, /*ByteCodeGenerator* byteCodeGenerator, FuncInfo* funcInfo,*/ Scope* scope);
  237. //
  238. // Turn on capturesAll for a Scope temporarily. Restore old capturesAll when this object
  239. // goes out of scope.
  240. //
  241. class AutoCapturesAllScope
  242. {
  243. private:
  244. Scope* scope;
  245. bool oldCapturesAll;
  246. public:
  247. AutoCapturesAllScope(Scope* scope, bool turnOn);
  248. ~AutoCapturesAllScope();
  249. bool OldCapturesAll() const
  250. {
  251. return oldCapturesAll;
  252. }
  253. };
  254. };
  255. }