ptree.h 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  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. struct Ident;
  7. typedef Ident *IdentPtr;
  8. class Scope;
  9. /***************************************************************************
  10. Flags for classifying node operators.
  11. ***************************************************************************/
  12. const uint fnopNone = 0x0000;
  13. const uint fnopConst = 0x0001; // constant
  14. const uint fnopLeaf = 0x0002; // leaf
  15. const uint fnopUni = 0x0004; // unary
  16. const uint fnopBin = 0x0008; // binary
  17. const uint fnopRel = 0x0010; // relational
  18. const uint fnopAsg = 0x0020; // assignment
  19. const uint fnopBreak = 0x0040; // break can be used within this statement
  20. const uint fnopContinue = 0x0080; // continue can be used within this statement
  21. const uint fnopCleanup = 0x0100; // requires cleanup (eg, with or for-in).
  22. const uint fnopJump = 0x0200;
  23. const uint fnopNotExprStmt = 0x0400;
  24. const uint fnopBinList = 0x0800;
  25. const uint fnopExprMask = (fnopLeaf|fnopUni|fnopBin);
  26. /***************************************************************************
  27. Flags for classifying parse nodes.
  28. ***************************************************************************/
  29. enum PNodeFlags : ushort
  30. {
  31. fpnNone = 0x0000,
  32. // knopFncDecl nodes.
  33. fpnArguments_overriddenByDecl = 0x0001, // function has a let/const decl, class or nested function named 'arguments', which overrides the built-in arguments object in the body
  34. fpnArguments_overriddenInParam = 0x0002, // function has a parameter named arguments
  35. fpnArguments_varDeclaration = 0x0004, // function has a var declaration named 'arguments', which may change the way an 'arguments' identifier is resolved
  36. // knopVarDecl nodes.
  37. fpnArguments = 0x0008,
  38. fpnHidden = 0x0010,
  39. // Statement nodes.
  40. fpnExplicitSemicolon = 0x0020, // statement terminated by an explicit semicolon
  41. fpnAutomaticSemicolon = 0x0040, // statement terminated by an automatic semicolon
  42. fpnMissingSemicolon = 0x0080, // statement missing terminating semicolon, and is not applicable for automatic semicolon insertion
  43. fpnDclList = 0x0100, // statement is a declaration list
  44. fpnSyntheticNode = 0x0200, // node is added by the parser or does it represent user code
  45. fpnIndexOperator = 0x0400, // dot operator is an optimization of an index operator
  46. fpnJumbStatement = 0x0800, // break or continue that was removed by error recovery
  47. // Unary/Binary nodes
  48. fpnCanFlattenConcatExpr = 0x1000, // the result of the binary operation can participate in concat N
  49. // Potentially overlapping traversal flags
  50. // These flags are set and cleared during a single node traversal and their values can be used in other node traversals.
  51. fpnMemberReference = 0x2000, // The node is a member reference symbol
  52. fpnCapturesSyms = 0x4000, // The node is a statement (or contains a sub-statement)
  53. // that captures symbols.
  54. };
  55. /***************************************************************************
  56. Data structs for ParseNodes. ParseNode includes a union of these.
  57. ***************************************************************************/
  58. struct PnUni
  59. {
  60. ParseNodePtr pnode1;
  61. };
  62. struct PnBin
  63. {
  64. ParseNodePtr pnodeNext;
  65. ParseNodePtr pnode1;
  66. ParseNodePtr pnode2;
  67. };
  68. struct PnTri
  69. {
  70. ParseNodePtr pnodeNext;
  71. ParseNodePtr pnode1;
  72. ParseNodePtr pnode2;
  73. ParseNodePtr pnode3;
  74. };
  75. struct PnSlot
  76. {
  77. uint slotIndex;
  78. };
  79. struct PnUniSlot : PnUni
  80. {
  81. uint slotIndex;
  82. uint staticFuncId;
  83. };
  84. struct PnInt
  85. {
  86. int32 lw;
  87. };
  88. struct PnFlt
  89. {
  90. double dbl;
  91. bool maybeInt : 1;
  92. };
  93. class Symbol;
  94. struct PidRefStack;
  95. struct PnPid
  96. {
  97. IdentPtr pid;
  98. Symbol **symRef;
  99. Symbol *sym;
  100. UnifiedRegex::RegexPattern* regexPattern;
  101. uint regexPatternIndex;
  102. void SetSymRef(PidRefStack *ref);
  103. Symbol **GetSymRef() const { return symRef; }
  104. Js::PropertyId PropertyIdFromNameNode() const;
  105. };
  106. struct PnVar
  107. {
  108. ParseNodePtr pnodeNext;
  109. IdentPtr pid;
  110. Symbol *sym;
  111. Symbol **symRef;
  112. ParseNodePtr pnodeInit;
  113. BOOLEAN isSwitchStmtDecl;
  114. BOOLEAN isBlockScopeFncDeclVar;
  115. void InitDeclNode(IdentPtr name, ParseNodePtr initExpr)
  116. {
  117. this->pid = name;
  118. this->pnodeInit = initExpr;
  119. this->pnodeNext = nullptr;
  120. this->sym = nullptr;
  121. this->symRef = nullptr;
  122. this->isSwitchStmtDecl = false;
  123. this->isBlockScopeFncDeclVar = false;
  124. }
  125. };
  126. struct PnLabel
  127. {
  128. IdentPtr pid;
  129. ParseNodePtr pnodeNext;
  130. };
  131. struct PnArrLit : PnUni
  132. {
  133. uint count;
  134. uint spreadCount;
  135. BYTE arrayOfTaggedInts:1; // indicates that array initializer nodes are all tagged ints
  136. BYTE arrayOfInts:1; // indicates that array initializer nodes are all ints
  137. BYTE arrayOfNumbers:1; // indicates that array initializer nodes are all numbers
  138. BYTE hasMissingValues:1;
  139. };
  140. class FuncInfo;
  141. enum PnodeBlockType : unsigned
  142. {
  143. Global,
  144. Function,
  145. Regular,
  146. Parameter
  147. };
  148. enum FncFlags
  149. {
  150. kFunctionNone = 0,
  151. kFunctionNested = 1 << 0, // True if function is nested in another.
  152. kFunctionDeclaration = 1 << 1, // is this a declaration or an expression?
  153. kFunctionCallsEval = 1 << 2, // function uses eval
  154. kFunctionUsesArguments = 1 << 3, // function uses arguments
  155. kFunctionHasHeapArguments = 1 << 4, // function's "arguments" escape the scope
  156. kFunctionHasReferenceableBuiltInArguments = 1 << 5, // the built-in 'arguments' object is referenceable in the function
  157. kFunctionIsAccessor = 1 << 6, // function is a property getter or setter
  158. kFunctionHasNonThisStmt = 1 << 7,
  159. kFunctionStrictMode = 1 << 8,
  160. kFunctionDoesNotEscape = 1 << 9, // function is known not to escape its declaring scope
  161. kFunctionIsModule = 1 << 10, // function is a module body
  162. kFunctionHasThisStmt = 1 << 11, // function has at least one this.assignment and might be a constructor
  163. kFunctionHasWithStmt = 1 << 12, // function (or child) uses with
  164. kFunctionIsLambda = 1 << 13,
  165. kFunctionChildCallsEval = 1 << 14,
  166. kFunctionHasNonSimpleParameterList = 1 << 15,
  167. kFunctionHasSuperReference = 1 << 16,
  168. kFunctionIsMethod = 1 << 17,
  169. kFunctionIsClassConstructor = 1 << 18, // function is a class constructor
  170. kFunctionIsBaseClassConstructor = 1 << 19, // function is a base class constructor
  171. kFunctionIsClassMember = 1 << 20, // function is a class member
  172. kFunctionNameIsHidden = 1 << 21, // True if a named function expression has its name hidden from nested functions
  173. kFunctionIsGeneratedDefault = 1 << 22, // Is the function generated by us as a default (e.g. default class constructor)
  174. kFunctionHasDefaultArguments = 1 << 23, // Function has one or more ES6 default arguments
  175. kFunctionIsStaticMember = 1 << 24,
  176. kFunctionIsGenerator = 1 << 25, // Function is an ES6 generator function
  177. kFunctionAsmjsMode = 1 << 26,
  178. kFunctionHasNewTargetReference = 1 << 27, // function has a reference to new.target
  179. kFunctionIsAsync = 1 << 28, // function is async
  180. kFunctionHasDirectSuper = 1 << 29, // super()
  181. kFunctionIsDefaultModuleExport = 1 << 30, // function is the default export of a module
  182. kFunctionHasAnyWriteToFormals = 1 << 31 // To Track if there are any writes to formals.
  183. };
  184. struct RestorePoint;
  185. struct DeferredFunctionStub;
  186. struct PnFnc
  187. {
  188. ParseNodePtr pnodeNext;
  189. ParseNodePtr pnodeName;
  190. IdentPtr pid;
  191. LPCOLESTR hint;
  192. uint32 hintLength;
  193. uint32 hintOffset;
  194. bool isNameIdentifierRef;
  195. bool nestedFuncEscapes;
  196. ParseNodePtr pnodeScopes;
  197. ParseNodePtr pnodeBodyScope;
  198. ParseNodePtr pnodeParams;
  199. ParseNodePtr pnodeVars;
  200. ParseNodePtr pnodeBody;
  201. ParseNodePtr pnodeRest;
  202. FuncInfo *funcInfo; // function information gathered during byte code generation
  203. Scope *scope;
  204. uint nestedCount; // Nested function count (valid until children have been processed)
  205. uint nestedIndex; // Index within the parent function
  206. uint16 firstDefaultArg; // Position of the first default argument, if any
  207. unsigned int fncFlags;
  208. int32 astSize;
  209. size_t cbMin; // Min an Lim UTF8 offsets.
  210. size_t cbLim;
  211. ULONG lineNumber; // Line number relative to the current source buffer of the function declaration.
  212. ULONG columnNumber; // Column number of the declaration.
  213. Js::LocalFunctionId functionId;
  214. #if DBG
  215. Js::LocalFunctionId deferredParseNextFunctionId;
  216. #endif
  217. RestorePoint *pRestorePoint;
  218. DeferredFunctionStub *deferredStub;
  219. bool canBeDeferred;
  220. bool isBodyAndParamScopeMerged; // Indicates whether the param scope and the body scope of the function can be merged together or not.
  221. // We cannot merge both scopes together if there is any closure capture or eval is present in the param scope.
  222. bool fibPreventsDeferral;
  223. static const int32 MaxStackClosureAST = 800000;
  224. static bool CanBeRedeferred(unsigned int flags) { return !(flags & (kFunctionIsGenerator | kFunctionIsAsync)); }
  225. private:
  226. void SetFlags(uint flags, bool set)
  227. {
  228. if (set)
  229. {
  230. fncFlags |= flags;
  231. }
  232. else
  233. {
  234. fncFlags &= ~flags;
  235. }
  236. }
  237. bool HasFlags(uint flags) const
  238. {
  239. return (fncFlags & flags) == flags;
  240. }
  241. bool HasAnyFlags(uint flags) const
  242. {
  243. return (fncFlags & flags) != 0;
  244. }
  245. bool HasNoFlags(uint flags) const
  246. {
  247. return (fncFlags & flags) == 0;
  248. }
  249. public:
  250. void ClearFlags()
  251. {
  252. fncFlags = kFunctionNone;
  253. canBeDeferred = false;
  254. isBodyAndParamScopeMerged = true;
  255. }
  256. void SetAsmjsMode(bool set = true) { SetFlags(kFunctionAsmjsMode, set); }
  257. void SetCallsEval(bool set = true) { SetFlags(kFunctionCallsEval, set); }
  258. void SetChildCallsEval(bool set = true) { SetFlags(kFunctionChildCallsEval, set); }
  259. void SetDeclaration(bool set = true) { SetFlags(kFunctionDeclaration, set); }
  260. void SetDoesNotEscape(bool set = true) { SetFlags(kFunctionDoesNotEscape, set); }
  261. void SetHasDefaultArguments(bool set = true) { SetFlags(kFunctionHasDefaultArguments, set); }
  262. void SetHasHeapArguments(bool set = true) { SetFlags(kFunctionHasHeapArguments, set); }
  263. void SetHasAnyWriteToFormals(bool set = true) { SetFlags((uint)kFunctionHasAnyWriteToFormals, set); }
  264. void SetHasNonSimpleParameterList(bool set = true) { SetFlags(kFunctionHasNonSimpleParameterList, set); }
  265. void SetHasNonThisStmt(bool set = true) { SetFlags(kFunctionHasNonThisStmt, set); }
  266. void SetHasReferenceableBuiltInArguments(bool set = true) { SetFlags(kFunctionHasReferenceableBuiltInArguments, set); }
  267. void SetHasSuperReference(bool set = true) { SetFlags(kFunctionHasSuperReference, set); }
  268. void SetHasDirectSuper(bool set = true) { SetFlags(kFunctionHasDirectSuper, set); }
  269. void SetHasNewTargetReference(bool set = true) { SetFlags(kFunctionHasNewTargetReference, set); }
  270. void SetHasThisStmt(bool set = true) { SetFlags(kFunctionHasThisStmt, set); }
  271. void SetHasWithStmt(bool set = true) { SetFlags(kFunctionHasWithStmt, set); }
  272. void SetIsAccessor(bool set = true) { SetFlags(kFunctionIsAccessor, set); }
  273. void SetIsAsync(bool set = true) { SetFlags(kFunctionIsAsync, set); }
  274. void SetIsClassConstructor(bool set = true) { SetFlags(kFunctionIsClassConstructor, set); }
  275. void SetIsBaseClassConstructor(bool set = true) { SetFlags(kFunctionIsBaseClassConstructor, set); }
  276. void SetIsClassMember(bool set = true) { SetFlags(kFunctionIsClassMember, set); }
  277. void SetIsGeneratedDefault(bool set = true) { SetFlags(kFunctionIsGeneratedDefault, set); }
  278. void SetIsGenerator(bool set = true) { SetFlags(kFunctionIsGenerator, set); }
  279. void SetIsLambda(bool set = true) { SetFlags(kFunctionIsLambda, set); }
  280. void SetIsMethod(bool set = true) { SetFlags(kFunctionIsMethod, set); }
  281. void SetIsStaticMember(bool set = true) { SetFlags(kFunctionIsStaticMember, set); }
  282. void SetNameIsHidden(bool set = true) { SetFlags(kFunctionNameIsHidden, set); }
  283. void SetNested(bool set = true) { SetFlags(kFunctionNested, set); }
  284. void SetStrictMode(bool set = true) { SetFlags(kFunctionStrictMode, set); }
  285. void SetIsModule(bool set = true) { SetFlags(kFunctionIsModule, set); }
  286. void SetUsesArguments(bool set = true) { SetFlags(kFunctionUsesArguments, set); }
  287. void SetIsDefaultModuleExport(bool set = true) { SetFlags(kFunctionIsDefaultModuleExport, set); }
  288. void SetNestedFuncEscapes(bool set = true) { nestedFuncEscapes = set; }
  289. void SetCanBeDeferred(bool set = true) { canBeDeferred = set; }
  290. void ResetBodyAndParamScopeMerged() { isBodyAndParamScopeMerged = false; }
  291. void SetFIBPreventsDeferral(bool set = true) { fibPreventsDeferral = set; }
  292. bool CallsEval() const { return HasFlags(kFunctionCallsEval); }
  293. bool ChildCallsEval() const { return HasFlags(kFunctionChildCallsEval); }
  294. bool DoesNotEscape() const { return HasFlags(kFunctionDoesNotEscape); }
  295. bool GetArgumentsObjectEscapes() const { return HasFlags(kFunctionHasHeapArguments); }
  296. bool GetAsmjsMode() const { return HasFlags(kFunctionAsmjsMode); }
  297. bool GetStrictMode() const { return HasFlags(kFunctionStrictMode); }
  298. bool HasDefaultArguments() const { return HasFlags(kFunctionHasDefaultArguments); }
  299. bool HasHeapArguments() const { return true; /* HasFlags(kFunctionHasHeapArguments); Disabling stack arguments. Always return HeapArguments as True */ }
  300. bool HasAnyWriteToFormals() const { return HasFlags((uint)kFunctionHasAnyWriteToFormals); }
  301. bool HasOnlyThisStmts() const { return !HasFlags(kFunctionHasNonThisStmt); }
  302. bool HasReferenceableBuiltInArguments() const { return HasFlags(kFunctionHasReferenceableBuiltInArguments); }
  303. bool HasSuperReference() const { return HasFlags(kFunctionHasSuperReference); }
  304. bool HasDirectSuper() const { return HasFlags(kFunctionHasDirectSuper); }
  305. bool HasNewTargetReference() const { return HasFlags(kFunctionHasNewTargetReference); }
  306. bool HasNonSimpleParameterList() { return HasFlags(kFunctionHasNonSimpleParameterList); }
  307. bool HasThisStmt() const { return HasFlags(kFunctionHasThisStmt); }
  308. bool HasWithStmt() const { return HasFlags(kFunctionHasWithStmt); }
  309. bool IsAccessor() const { return HasFlags(kFunctionIsAccessor); }
  310. bool IsAsync() const { return HasFlags(kFunctionIsAsync); }
  311. bool IsConstructor() const { return HasNoFlags(kFunctionIsAsync|kFunctionIsLambda|kFunctionIsAccessor); }
  312. bool IsClassConstructor() const { return HasFlags(kFunctionIsClassConstructor); }
  313. bool IsBaseClassConstructor() const { return HasFlags(kFunctionIsBaseClassConstructor); }
  314. bool IsClassMember() const { return HasFlags(kFunctionIsClassMember); }
  315. bool IsDeclaration() const { return HasFlags(kFunctionDeclaration); }
  316. bool IsGeneratedDefault() const { return HasFlags(kFunctionIsGeneratedDefault); }
  317. bool IsGenerator() const { return HasFlags(kFunctionIsGenerator); }
  318. bool IsCoroutine() const { return HasAnyFlags(kFunctionIsGenerator | kFunctionIsAsync); }
  319. bool IsLambda() const { return HasFlags(kFunctionIsLambda); }
  320. bool IsMethod() const { return HasFlags(kFunctionIsMethod); }
  321. bool IsNested() const { return HasFlags(kFunctionNested); }
  322. bool IsStaticMember() const { return HasFlags(kFunctionIsStaticMember); }
  323. bool IsModule() const { return HasFlags(kFunctionIsModule); }
  324. bool NameIsHidden() const { return HasFlags(kFunctionNameIsHidden); }
  325. bool UsesArguments() const { return HasFlags(kFunctionUsesArguments); }
  326. bool IsDefaultModuleExport() const { return HasFlags(kFunctionIsDefaultModuleExport); }
  327. bool NestedFuncEscapes() const { return nestedFuncEscapes; }
  328. bool CanBeDeferred() const { return canBeDeferred; }
  329. bool IsBodyAndParamScopeMerged() { return isBodyAndParamScopeMerged; }
  330. bool FIBPreventsDeferral() const { return fibPreventsDeferral; }
  331. // Only allow the normal functions to be asm.js
  332. bool IsAsmJsAllowed() const { return (fncFlags & ~(
  333. kFunctionAsmjsMode |
  334. kFunctionNested |
  335. kFunctionDeclaration |
  336. kFunctionStrictMode |
  337. kFunctionNameIsHidden |
  338. kFunctionHasReferenceableBuiltInArguments |
  339. kFunctionHasNonThisStmt |
  340. // todo:: we shouldn't accept kFunctionHasAnyWriteToFormals on the asm module, but it looks like a bug is setting that flag incorrectly
  341. kFunctionHasAnyWriteToFormals
  342. )) == 0; }
  343. size_t LengthInBytes()
  344. {
  345. return cbLim - cbMin;
  346. }
  347. Symbol *GetFuncSymbol();
  348. void SetFuncSymbol(Symbol *sym);
  349. ParseNodePtr GetParamScope() const;
  350. ParseNodePtr GetBodyScope() const;
  351. ParseNodePtr GetTopLevelScope() const
  352. {
  353. // Top level scope will be the same for knopProg and knopFncDecl.
  354. return GetParamScope();
  355. }
  356. template<typename Fn>
  357. void MapContainerScopes(Fn fn)
  358. {
  359. fn(this->pnodeScopes->sxBlock.pnodeScopes);
  360. if (this->pnodeBodyScope != nullptr)
  361. {
  362. fn(this->pnodeBodyScope->sxBlock.pnodeScopes);
  363. }
  364. }
  365. };
  366. struct PnClass
  367. {
  368. ParseNodePtr pnodeName;
  369. ParseNodePtr pnodeDeclName;
  370. ParseNodePtr pnodeBlock;
  371. ParseNodePtr pnodeConstructor;
  372. ParseNodePtr pnodeMembers;
  373. ParseNodePtr pnodeStaticMembers;
  374. ParseNodePtr pnodeExtends;
  375. bool isDefaultModuleExport;
  376. void SetIsDefaultModuleExport(bool set) { isDefaultModuleExport = set; }
  377. bool IsDefaultModuleExport() const { return isDefaultModuleExport; }
  378. };
  379. struct PnExportDefault
  380. {
  381. ParseNodePtr pnodeExpr;
  382. };
  383. struct PnStrTemplate
  384. {
  385. ParseNodePtr pnodeStringLiterals;
  386. ParseNodePtr pnodeStringRawLiterals;
  387. ParseNodePtr pnodeSubstitutionExpressions;
  388. uint16 countStringLiterals;
  389. BYTE isTaggedTemplate:1;
  390. };
  391. struct PnProg : PnFnc
  392. {
  393. ParseNodePtr pnodeLastValStmt;
  394. bool m_UsesArgumentsAtGlobal;
  395. };
  396. struct PnModule : PnProg
  397. {
  398. ModuleImportOrExportEntryList* localExportEntries;
  399. ModuleImportOrExportEntryList* indirectExportEntries;
  400. ModuleImportOrExportEntryList* starExportEntries;
  401. ModuleImportOrExportEntryList* importEntries;
  402. IdentPtrList* requestedModules;
  403. };
  404. struct PnCall
  405. {
  406. ParseNodePtr pnodeNext;
  407. ParseNodePtr pnodeTarget;
  408. ParseNodePtr pnodeArgs;
  409. uint16 argCount;
  410. uint16 spreadArgCount;
  411. BYTE callOfConstants : 1;
  412. BYTE isApplyCall : 1;
  413. BYTE isEvalCall : 1;
  414. BYTE hasDestructuring : 1;
  415. };
  416. struct PnStmt
  417. {
  418. ParseNodePtr pnodeOuter;
  419. // Set by parsing code, used by code gen.
  420. uint grfnop;
  421. // Needed for byte code gen.
  422. Js::ByteCodeLabel breakLabel;
  423. Js::ByteCodeLabel continueLabel;
  424. };
  425. struct PnBlock : PnStmt
  426. {
  427. ParseNodePtr pnodeStmt;
  428. ParseNodePtr pnodeLastValStmt;
  429. ParseNodePtr pnodeLexVars;
  430. ParseNodePtr pnodeScopes;
  431. ParseNodePtr pnodeNext;
  432. Scope *scope;
  433. ParseNodePtr enclosingBlock;
  434. int blockId;
  435. PnodeBlockType blockType:2;
  436. BYTE callsEval:1;
  437. BYTE childCallsEval:1;
  438. void SetCallsEval(bool does) { callsEval = does; }
  439. bool GetCallsEval() const { return callsEval; }
  440. void SetChildCallsEval(bool does) { childCallsEval = does; }
  441. bool GetChildCallsEval() const { return childCallsEval; }
  442. void SetEnclosingBlock(ParseNodePtr pnode) { enclosingBlock = pnode; }
  443. ParseNodePtr GetEnclosingBlock() const { return enclosingBlock; }
  444. bool HasBlockScopedContent() const;
  445. };
  446. struct PnJump : PnStmt
  447. {
  448. ParseNodePtr pnodeTarget;
  449. bool hasExplicitTarget;
  450. };
  451. struct PnLoop : PnStmt
  452. {
  453. // Needed for byte code gen
  454. uint loopId;
  455. };
  456. struct PnWhile : PnLoop
  457. {
  458. ParseNodePtr pnodeCond;
  459. ParseNodePtr pnodeBody;
  460. };
  461. struct PnWith : PnStmt
  462. {
  463. ParseNodePtr pnodeObj;
  464. ParseNodePtr pnodeBody;
  465. ParseNodePtr pnodeScopes;
  466. ParseNodePtr pnodeNext;
  467. Scope *scope;
  468. };
  469. struct PnParamPattern
  470. {
  471. ParseNodePtr pnodeNext;
  472. Js::RegSlot location;
  473. ParseNodePtr pnode1;
  474. };
  475. struct PnIf : PnStmt
  476. {
  477. ParseNodePtr pnodeCond;
  478. ParseNodePtr pnodeTrue;
  479. ParseNodePtr pnodeFalse;
  480. };
  481. struct PnHelperCall2 {
  482. ParseNodePtr pnodeArg1;
  483. ParseNodePtr pnodeArg2;
  484. int helperId;
  485. };
  486. struct PnForInOrForOf : PnLoop
  487. {
  488. ParseNodePtr pnodeObj;
  489. ParseNodePtr pnodeBody;
  490. ParseNodePtr pnodeLval;
  491. ParseNodePtr pnodeBlock;
  492. Js::RegSlot itemLocation;
  493. };
  494. struct PnFor : PnLoop
  495. {
  496. ParseNodePtr pnodeCond;
  497. ParseNodePtr pnodeBody;
  498. ParseNodePtr pnodeInit;
  499. ParseNodePtr pnodeIncr;
  500. ParseNodePtr pnodeBlock;
  501. ParseNodePtr pnodeInverted;
  502. };
  503. struct PnSwitch : PnStmt
  504. {
  505. ParseNodePtr pnodeVal;
  506. ParseNodePtr pnodeCases;
  507. ParseNodePtr pnodeDefault;
  508. ParseNodePtr pnodeBlock;
  509. };
  510. struct PnCase : PnStmt
  511. {
  512. ParseNodePtr pnodeNext;
  513. ParseNodePtr pnodeExpr; // nullptr for default
  514. ParseNodePtr pnodeBody;
  515. Js::ByteCodeLabel labelCase;
  516. };
  517. struct PnReturn : PnStmt
  518. {
  519. ParseNodePtr pnodeExpr;
  520. };
  521. struct PnTryFinally : PnStmt
  522. {
  523. ParseNodePtr pnodeTry;
  524. ParseNodePtr pnodeFinally;
  525. };
  526. struct PnTryCatch : PnStmt
  527. {
  528. ParseNodePtr pnodeTry;
  529. ParseNodePtr pnodeCatch;
  530. };
  531. struct PnTry : PnStmt
  532. {
  533. ParseNodePtr pnodeBody;
  534. };
  535. struct PnCatch : PnStmt
  536. {
  537. ParseNodePtr pnodeNext;
  538. ParseNodePtr pnodeParam;
  539. ParseNodePtr pnodeBody;
  540. ParseNodePtr pnodeScopes;
  541. Scope *scope;
  542. };
  543. struct PnFinally : PnStmt
  544. {
  545. ParseNodePtr pnodeBody;
  546. };
  547. struct ParseNode
  548. {
  549. OpCode nop;
  550. ushort grfpn;
  551. charcount_t ichMin; // start offset into the original source buffer
  552. charcount_t ichLim; // end offset into the original source buffer
  553. Js::RegSlot location;
  554. bool isUsed; // indicates whether an expression such as x++ is used
  555. bool emitLabels;
  556. bool notEscapedUse; // Use by byte code generator. Currently, only used by child of knopComma
  557. bool isInList;
  558. bool isCallApplyTargetLoad;
  559. #ifdef EDIT_AND_CONTINUE
  560. ParseNodePtr parent;
  561. #endif
  562. union
  563. {
  564. PnArrLit sxArrLit; // Array literal
  565. PnBin sxBin; // binary operators
  566. PnBlock sxBlock; // block { }
  567. PnCall sxCall; // function call
  568. PnCase sxCase; // switch case
  569. PnCatch sxCatch; // { catch(e : expr) {body} }
  570. PnClass sxClass; // class declaration
  571. PnFinally sxFinally; // finally
  572. PnExportDefault sxExportDefault;// export default expr;
  573. PnFlt sxFlt; // double constant
  574. PnFnc sxFnc; // function declaration
  575. PnFor sxFor; // for loop
  576. PnForInOrForOf sxForInOrForOf; // for-in loop
  577. PnHelperCall2 sxHelperCall2; // call to helper
  578. PnIf sxIf; // if
  579. PnInt sxInt; // integer constant
  580. PnJump sxJump; // break and continue
  581. PnLabel sxLabel; // label nodes
  582. PnLoop sxLoop; // base for loop nodes
  583. PnModule sxModule; // global module
  584. PnPid sxPid; // identifier or string
  585. PnProg sxProg; // global program
  586. PnReturn sxReturn; // return [expr]
  587. PnStmt sxStmt; // base for statement nodes
  588. PnStrTemplate sxStrTemplate; // string template declaration
  589. PnSwitch sxSwitch; // switch
  590. PnTri sxTri; // ternary operator
  591. PnTry sxTry; // try-catch
  592. PnTryCatch sxTryCatch; // try-catch
  593. PnTryFinally sxTryFinally; // try-catch-finally
  594. PnUni sxUni; // unary operators
  595. PnVar sxVar; // variable declaration
  596. PnWhile sxWhile; // while and do-while loops
  597. PnWith sxWith; // with
  598. PnParamPattern sxParamPattern; // Destructure pattern for function/catch parameter
  599. };
  600. IdentPtr name()
  601. {
  602. if (this->nop == knopName || this->nop == knopStr)
  603. {
  604. return this->sxPid.pid;
  605. }
  606. else if (this->nop == knopVarDecl)
  607. {
  608. return this->sxVar.pid;
  609. }
  610. else if (this->nop == knopConstDecl)
  611. {
  612. return this->sxVar.pid;
  613. }
  614. return nullptr;
  615. }
  616. static const uint mpnopgrfnop[knopLim];
  617. static uint Grfnop(int nop)
  618. {
  619. Assert(nop < knopLim);
  620. return nop < knopLim ? mpnopgrfnop[nop] : fnopNone;
  621. }
  622. BOOL IsStatement()
  623. {
  624. return (nop >= knopList && nop != knopLabel) || ((Grfnop(nop) & fnopAsg) != 0);
  625. }
  626. uint Grfnop(void)
  627. {
  628. Assert(nop < knopLim);
  629. return nop < knopLim ? mpnopgrfnop[nop] : fnopNone;
  630. }
  631. charcount_t LengthInCodepoints() const
  632. {
  633. return (this->ichLim - this->ichMin);
  634. }
  635. // This node is a function decl node and function has a var declaration named 'arguments',
  636. bool HasVarArguments() const
  637. {
  638. return ((nop == knopFncDecl) && (grfpn & PNodeFlags::fpnArguments_varDeclaration));
  639. }
  640. bool CapturesSyms() const
  641. {
  642. return (grfpn & PNodeFlags::fpnCapturesSyms) != 0;
  643. }
  644. void SetCapturesSyms()
  645. {
  646. grfpn |= PNodeFlags::fpnCapturesSyms;
  647. }
  648. bool IsInList() const { return this->isInList; }
  649. void SetIsInList() { this->isInList = true; }
  650. bool IsNotEscapedUse() const { return this->notEscapedUse; }
  651. void SetNotEscapedUse() { this->notEscapedUse = true; }
  652. bool CanFlattenConcatExpr() const { return !!(this->grfpn & PNodeFlags::fpnCanFlattenConcatExpr); }
  653. bool IsCallApplyTargetLoad() { return isCallApplyTargetLoad; }
  654. void SetIsCallApplyTargetLoad() { isCallApplyTargetLoad = true; }
  655. bool IsVarLetOrConst() const
  656. {
  657. return this->nop == knopVarDecl || this->nop == knopLetDecl || this->nop == knopConstDecl;
  658. }
  659. ParseNodePtr GetFormalNext()
  660. {
  661. ParseNodePtr pnodeNext = nullptr;
  662. if (nop == knopParamPattern)
  663. {
  664. pnodeNext = this->sxParamPattern.pnodeNext;
  665. }
  666. else
  667. {
  668. Assert(IsVarLetOrConst());
  669. pnodeNext = this->sxVar.pnodeNext;
  670. }
  671. return pnodeNext;
  672. }
  673. bool IsPattern() const
  674. {
  675. return nop == knopObjectPattern || nop == knopArrayPattern;
  676. }
  677. #if DBG_DUMP
  678. void Dump();
  679. #endif
  680. };
  681. const int kcbPnNone = offsetof(ParseNode, sxUni);
  682. const int kcbPnArrLit = kcbPnNone + sizeof(PnArrLit);
  683. const int kcbPnBin = kcbPnNone + sizeof(PnBin);
  684. const int kcbPnBlock = kcbPnNone + sizeof(PnBlock);
  685. const int kcbPnCall = kcbPnNone + sizeof(PnCall);
  686. const int kcbPnCase = kcbPnNone + sizeof(PnCase);
  687. const int kcbPnCatch = kcbPnNone + sizeof(PnCatch);
  688. const int kcbPnClass = kcbPnNone + sizeof(PnClass);
  689. const int kcbPnExportDefault= kcbPnNone + sizeof(PnExportDefault);
  690. const int kcbPnFinally = kcbPnNone + sizeof(PnFinally);
  691. const int kcbPnFlt = kcbPnNone + sizeof(PnFlt);
  692. const int kcbPnFnc = kcbPnNone + sizeof(PnFnc);
  693. const int kcbPnFor = kcbPnNone + sizeof(PnFor);
  694. const int kcbPnForIn = kcbPnNone + sizeof(PnForInOrForOf);
  695. const int kcbPnForOf = kcbPnNone + sizeof(PnForInOrForOf);
  696. const int kcbPnHelperCall3 = kcbPnNone + sizeof(PnHelperCall2);
  697. const int kcbPnIf = kcbPnNone + sizeof(PnIf);
  698. const int kcbPnInt = kcbPnNone + sizeof(PnInt);
  699. const int kcbPnJump = kcbPnNone + sizeof(PnJump);
  700. const int kcbPnLabel = kcbPnNone + sizeof(PnLabel);
  701. const int kcbPnModule = kcbPnNone + sizeof(PnModule);
  702. const int kcbPnPid = kcbPnNone + sizeof(PnPid);
  703. const int kcbPnProg = kcbPnNone + sizeof(PnProg);
  704. const int kcbPnReturn = kcbPnNone + sizeof(PnReturn);
  705. const int kcbPnSlot = kcbPnNone + sizeof(PnSlot);
  706. const int kcbPnStrTemplate = kcbPnNone + sizeof(PnStrTemplate);
  707. const int kcbPnSwitch = kcbPnNone + sizeof(PnSwitch);
  708. const int kcbPnTri = kcbPnNone + sizeof(PnTri);
  709. const int kcbPnTry = kcbPnNone + sizeof(PnTry);
  710. const int kcbPnTryCatch = kcbPnNone + sizeof(PnTryCatch);
  711. const int kcbPnTryFinally = kcbPnNone + sizeof(PnTryFinally);
  712. const int kcbPnUni = kcbPnNone + sizeof(PnUni);
  713. const int kcbPnUniSlot = kcbPnNone + sizeof(PnUniSlot);
  714. const int kcbPnVar = kcbPnNone + sizeof(PnVar);
  715. const int kcbPnWhile = kcbPnNone + sizeof(PnWhile);
  716. const int kcbPnWith = kcbPnNone + sizeof(PnWith);
  717. const int kcbPnParamPattern = kcbPnNone + sizeof(PnParamPattern);
  718. #define AssertNodeMem(pnode) AssertPvCb(pnode, kcbPnNone)
  719. #define AssertNodeMemN(pnode) AssertPvCbN(pnode, kcbPnNone)