ptree.h 27 KB

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