ptree.h 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084
  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. const uint fnopAllowDefer = 0x1000; // allow to be created during defer parse
  27. /***************************************************************************
  28. Flags for classifying parse nodes.
  29. ***************************************************************************/
  30. enum PNodeFlags : ushort
  31. {
  32. fpnNone = 0x0000,
  33. // knopFncDecl nodes.
  34. 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
  35. fpnArguments_overriddenInParam = 0x0002, // function has a parameter named arguments
  36. fpnArguments_varDeclaration = 0x0004, // function has a var declaration named 'arguments', which may change the way an 'arguments' identifier is resolved
  37. // knopVarDecl nodes.
  38. fpnArguments = 0x0008,
  39. fpnHidden = 0x0010,
  40. // Statement nodes.
  41. fpnExplicitSemicolon = 0x0020, // statement terminated by an explicit semicolon
  42. fpnAutomaticSemicolon = 0x0040, // statement terminated by an automatic semicolon
  43. fpnMissingSemicolon = 0x0080, // statement missing terminating semicolon, and is not applicable for automatic semicolon insertion
  44. fpnDclList = 0x0100, // statement is a declaration list
  45. fpnSyntheticNode = 0x0200, // node is added by the parser or does it represent user code
  46. fpnIndexOperator = 0x0400, // dot operator is an optimization of an index operator
  47. fpnJumbStatement = 0x0800, // break or continue that was removed by error recovery
  48. // Unary/Binary nodes
  49. fpnCanFlattenConcatExpr = 0x1000, // the result of the binary operation can participate in concat N
  50. // Potentially overlapping traversal flags
  51. // These flags are set and cleared during a single node traversal and their values can be used in other node traversals.
  52. fpnMemberReference = 0x2000, // The node is a member reference symbol
  53. fpnCapturesSyms = 0x4000, // The node is a statement (or contains a sub-statement)
  54. // that captures symbols.
  55. fpnSpecialSymbol = 0x8000,
  56. };
  57. /***************************************************************************
  58. Data structs for ParseNodes.
  59. ***************************************************************************/
  60. class ParseNodeUni;
  61. class ParseNodeBin;
  62. class ParseNodeTri;
  63. class ParseNodeInt;
  64. class ParseNodeFloat;
  65. class ParseNodeRegExp;
  66. class ParseNodeStr;
  67. class ParseNodeName;
  68. class ParseNodeVar;
  69. class ParseNodeCall;
  70. class ParseNodeSuperCall;
  71. class ParseNodeSpecialName;
  72. class ParseNodeExportDefault;
  73. class ParseNodeStrTemplate;
  74. class ParseNodeSuperReference;
  75. class ParseNodeArrLit;
  76. class ParseNodeClass;
  77. class ParseNodeParamPattern;
  78. class ParseNodeStmt;
  79. class ParseNodeBlock;
  80. class ParseNodeJump;
  81. class ParseNodeWith;
  82. class ParseNodeIf;
  83. class ParseNodeSwitch;
  84. class ParseNodeCase;
  85. class ParseNodeReturn;
  86. class ParseNodeTryFinally;
  87. class ParseNodeTryCatch;
  88. class ParseNodeTry;
  89. class ParseNodeCatch;
  90. class ParseNodeFinally;
  91. class ParseNodeLoop;
  92. class ParseNodeWhile;
  93. class ParseNodeFor;
  94. class ParseNodeForInOrForOf;
  95. class ParseNodeFnc;
  96. class ParseNodeProg;
  97. class ParseNodeModule;
  98. class ParseNode
  99. {
  100. public:
  101. ParseNode(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  102. ParseNodeUni * AsParseNodeUni();
  103. ParseNodeBin * AsParseNodeBin();
  104. ParseNodeTri * AsParseNodeTri();
  105. ParseNodeInt * AsParseNodeInt();
  106. ParseNodeFloat * AsParseNodeFloat();
  107. ParseNodeRegExp * AsParseNodeRegExp();
  108. ParseNodeVar * AsParseNodeVar();
  109. ParseNodeStr * AsParseNodeStr();
  110. ParseNodeName * AsParseNodeName();
  111. ParseNodeSpecialName * AsParseNodeSpecialName();
  112. ParseNodeExportDefault * AsParseNodeExportDefault();
  113. ParseNodeStrTemplate * AsParseNodeStrTemplate();
  114. ParseNodeSuperReference * AsParseNodeSuperReference();
  115. ParseNodeArrLit * AsParseNodeArrLit();
  116. ParseNodeCall * AsParseNodeCall();
  117. ParseNodeSuperCall * AsParseNodeSuperCall();
  118. ParseNodeClass * AsParseNodeClass();
  119. ParseNodeParamPattern * AsParseNodeParamPattern();
  120. ParseNodeStmt * AsParseNodeStmt();
  121. ParseNodeBlock * AsParseNodeBlock();
  122. ParseNodeJump * AsParseNodeJump();
  123. ParseNodeWith * AsParseNodeWith();
  124. ParseNodeIf * AsParseNodeIf();
  125. ParseNodeSwitch * AsParseNodeSwitch();
  126. ParseNodeCase * AsParseNodeCase();
  127. ParseNodeReturn * AsParseNodeReturn();
  128. ParseNodeTryFinally * AsParseNodeTryFinally();
  129. ParseNodeTryCatch * AsParseNodeTryCatch();
  130. ParseNodeTry * AsParseNodeTry();
  131. ParseNodeCatch * AsParseNodeCatch();
  132. ParseNodeFinally * AsParseNodeFinally();
  133. ParseNodeLoop * AsParseNodeLoop();
  134. ParseNodeWhile * AsParseNodeWhile();
  135. ParseNodeFor * AsParseNodeFor();
  136. ParseNodeForInOrForOf * AsParseNodeForInOrForOf();
  137. ParseNodeFnc * AsParseNodeFnc();
  138. ParseNodeProg * AsParseNodeProg();
  139. ParseNodeModule * AsParseNodeModule();
  140. static uint Grfnop(int nop)
  141. {
  142. Assert(nop < knopLim);
  143. return nop < knopLim ? mpnopgrfnop[nop] : fnopNone;
  144. }
  145. BOOL IsStatement()
  146. {
  147. return nop >= knopList || ((Grfnop(nop) & fnopAsg) != 0);
  148. }
  149. uint Grfnop(void)
  150. {
  151. Assert(nop < knopLim);
  152. return nop < knopLim ? mpnopgrfnop[nop] : fnopNone;
  153. }
  154. IdentPtr name();
  155. charcount_t LengthInCodepoints() const
  156. {
  157. return (this->ichLim - this->ichMin);
  158. }
  159. // This node is a function decl node and function has a var declaration named 'arguments',
  160. bool HasVarArguments() const
  161. {
  162. return ((nop == knopFncDecl) && (grfpn & PNodeFlags::fpnArguments_varDeclaration));
  163. }
  164. bool CapturesSyms() const
  165. {
  166. return (grfpn & PNodeFlags::fpnCapturesSyms) != 0;
  167. }
  168. void SetCapturesSyms()
  169. {
  170. grfpn |= PNodeFlags::fpnCapturesSyms;
  171. }
  172. bool IsInList() const { return this->isInList; }
  173. void SetIsInList() { this->isInList = true; }
  174. bool IsNotEscapedUse() const { return this->notEscapedUse; }
  175. void SetNotEscapedUse() { this->notEscapedUse = true; }
  176. bool CanFlattenConcatExpr() const { return !!(this->grfpn & PNodeFlags::fpnCanFlattenConcatExpr); }
  177. bool IsCallApplyTargetLoad() { return isCallApplyTargetLoad; }
  178. void SetIsCallApplyTargetLoad() { isCallApplyTargetLoad = true; }
  179. bool IsPatternDeclaration() { return isPatternDeclaration; }
  180. void SetIsPatternDeclaration() { isPatternDeclaration = true; }
  181. bool IsUserIdentifier();
  182. bool IsVarLetOrConst() const
  183. {
  184. return this->nop == knopVarDecl || this->nop == knopLetDecl || this->nop == knopConstDecl;
  185. }
  186. ParseNodePtr GetFormalNext();
  187. bool IsPattern() const
  188. {
  189. return nop == knopObjectPattern || nop == knopArrayPattern;
  190. }
  191. #if DBG_DUMP
  192. void Dump();
  193. #endif
  194. public:
  195. static const uint mpnopgrfnop[knopLim];
  196. OpCode nop;
  197. bool isUsed : 1; // indicates whether an expression such as x++ is used
  198. private:
  199. bool isInList : 1;
  200. // Use by byte code generator
  201. bool notEscapedUse : 1; // Currently, only used by child of knopComma
  202. bool isCallApplyTargetLoad : 1;
  203. // Use by bytecodegen to identify the current node is a destructuring pattern declaration node.
  204. bool isPatternDeclaration : 1;
  205. public:
  206. ushort grfpn;
  207. charcount_t ichMin; // start offset into the original source buffer
  208. charcount_t ichLim; // end offset into the original source buffer
  209. Js::RegSlot location;
  210. #ifdef EDIT_AND_CONTINUE
  211. ParseNodePtr parent;
  212. #endif
  213. };
  214. #define DISABLE_SELF_CAST(T) private: T * As##T()
  215. // unary operators
  216. class ParseNodeUni : public ParseNode
  217. {
  218. public:
  219. ParseNodeUni(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnode1);
  220. ParseNodePtr pnode1;
  221. DISABLE_SELF_CAST(ParseNodeUni);
  222. };
  223. // binary operators
  224. class ParseNodeBin : public ParseNode
  225. {
  226. public:
  227. ParseNodeBin(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnode1, ParseNode * pnode2);
  228. ParseNodePtr pnode1;
  229. ParseNodePtr pnode2;
  230. DISABLE_SELF_CAST(ParseNodeBin);
  231. };
  232. // ternary operator
  233. class ParseNodeTri : public ParseNode
  234. {
  235. public:
  236. ParseNodeTri(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  237. ParseNodePtr pnode1;
  238. ParseNodePtr pnode2;
  239. ParseNodePtr pnode3;
  240. DISABLE_SELF_CAST(ParseNodeTri);
  241. };
  242. // integer constant
  243. class ParseNodeInt : public ParseNode
  244. {
  245. public:
  246. ParseNodeInt(charcount_t ichMin, charcount_t ichMax, int32 lw);
  247. int32 lw;
  248. DISABLE_SELF_CAST(ParseNodeInt);
  249. };
  250. // double constant
  251. class ParseNodeFloat : public ParseNode
  252. {
  253. public:
  254. ParseNodeFloat(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  255. double dbl;
  256. bool maybeInt : 1;
  257. DISABLE_SELF_CAST(ParseNodeFloat);
  258. };
  259. class ParseNodeRegExp : public ParseNode
  260. {
  261. public:
  262. ParseNodeRegExp(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  263. UnifiedRegex::RegexPattern* regexPattern;
  264. uint regexPatternIndex;
  265. DISABLE_SELF_CAST(ParseNodeRegExp);
  266. };
  267. // identifier or string
  268. class ParseNodeStr : public ParseNode
  269. {
  270. public:
  271. ParseNodeStr(charcount_t ichMin, charcount_t ichLim, IdentPtr pid);
  272. IdentPtr const pid;
  273. DISABLE_SELF_CAST(ParseNodeStr);
  274. };
  275. class Symbol;
  276. struct PidRefStack;
  277. class ParseNodeName : public ParseNode
  278. {
  279. public:
  280. ParseNodeName(charcount_t ichMin, charcount_t ichLim, IdentPtr pid);
  281. IdentPtr const pid;
  282. private:
  283. Symbol **symRef;
  284. public:
  285. Symbol *sym;
  286. void SetSymRef(PidRefStack *ref);
  287. void ClearSymRef() { symRef = nullptr; }
  288. Symbol **GetSymRef() const { return symRef; }
  289. Js::PropertyId PropertyIdFromNameNode() const;
  290. bool IsSpecialName() { return isSpecialName; }
  291. DISABLE_SELF_CAST(ParseNodeName);
  292. protected:
  293. void SetIsSpecialName() { isSpecialName = true; }
  294. private:
  295. bool isSpecialName; // indicates a PnPid (knopName) is a special name like 'this' or 'super'
  296. };
  297. // variable declaration
  298. class ParseNodeVar : public ParseNode
  299. {
  300. public:
  301. ParseNodeVar(OpCode nop, charcount_t ichMin, charcount_t ichLim, IdentPtr name);
  302. ParseNodePtr pnodeNext;
  303. IdentPtr const pid;
  304. Symbol *sym;
  305. Symbol **symRef;
  306. ParseNodePtr pnodeInit;
  307. BOOLEAN isSwitchStmtDecl;
  308. BOOLEAN isBlockScopeFncDeclVar;
  309. DISABLE_SELF_CAST(ParseNodeVar);
  310. };
  311. // Array literal
  312. class ParseNodeArrLit : public ParseNodeUni
  313. {
  314. public:
  315. ParseNodeArrLit(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  316. uint count;
  317. uint spreadCount;
  318. BYTE arrayOfTaggedInts:1; // indicates that array initializer nodes are all tagged ints
  319. BYTE arrayOfInts:1; // indicates that array initializer nodes are all ints
  320. BYTE arrayOfNumbers:1; // indicates that array initializer nodes are all numbers
  321. BYTE hasMissingValues:1;
  322. DISABLE_SELF_CAST(ParseNodeArrLit);
  323. };
  324. class FuncInfo;
  325. enum PnodeBlockType : unsigned
  326. {
  327. Global,
  328. Function,
  329. Regular,
  330. Parameter
  331. };
  332. enum FncFlags : uint
  333. {
  334. kFunctionNone = 0,
  335. kFunctionNested = 1 << 0, // True if function is nested in another.
  336. kFunctionDeclaration = 1 << 1, // is this a declaration or an expression?
  337. kFunctionCallsEval = 1 << 2, // function uses eval
  338. kFunctionUsesArguments = 1 << 3, // function uses arguments
  339. kFunctionHasHeapArguments = 1 << 4, // function's "arguments" escape the scope
  340. kFunctionHasReferenceableBuiltInArguments = 1 << 5, // the built-in 'arguments' object is referenceable in the function
  341. kFunctionIsAccessor = 1 << 6, // function is a property getter or setter
  342. kFunctionHasNonThisStmt = 1 << 7,
  343. kFunctionStrictMode = 1 << 8,
  344. kFunctionHasDestructuredParams = 1 << 9,
  345. kFunctionIsModule = 1 << 10, // function is a module body
  346. kFunctionHasComputedName = 1 << 11,
  347. kFunctionHasWithStmt = 1 << 12, // function (or child) uses with
  348. kFunctionIsLambda = 1 << 13,
  349. kFunctionChildCallsEval = 1 << 14,
  350. kFunctionHasNonSimpleParameterList = 1 << 15,
  351. kFunctionHasSuperReference = 1 << 16,
  352. kFunctionIsMethod = 1 << 17,
  353. kFunctionIsClassConstructor = 1 << 18, // function is a class constructor
  354. kFunctionIsBaseClassConstructor = 1 << 19, // function is a base class constructor
  355. kFunctionIsClassMember = 1 << 20, // function is a class member
  356. kFunctionHasHomeObj = 1 << 21, // function has home object. Class or member functions need to have home obj.
  357. kFunctionIsGeneratedDefault = 1 << 22, // Is the function generated by us as a default (e.g. default class constructor)
  358. kFunctionHasDefaultArguments = 1 << 23, // Function has one or more ES6 default arguments
  359. kFunctionIsStaticMember = 1 << 24,
  360. kFunctionIsGenerator = 1 << 25, // Function is an ES6 generator function
  361. kFunctionAsmjsMode = 1 << 26,
  362. kFunctionIsDeclaredInParamScope = 1 << 27, // Function is declared in parameter scope (ex: inside default argument)
  363. kFunctionIsAsync = 1 << 28, // function is async
  364. kFunctionHasDirectSuper = 1 << 29, // super()
  365. kFunctionIsDefaultModuleExport = 1 << 30, // function is the default export of a module
  366. kFunctionHasAnyWriteToFormals = (uint)1 << 31 // To Track if there are any writes to formals.
  367. };
  368. struct RestorePoint;
  369. struct DeferredFunctionStub;
  370. namespace SuperRestrictionState {
  371. enum State {
  372. Disallowed = 0,
  373. CallAndPropertyAllowed = 1,
  374. PropertyAllowed = 2
  375. };
  376. }
  377. // function declaration
  378. class ParseNodeFnc : public ParseNode
  379. {
  380. public:
  381. ParseNodeFnc(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  382. ParseNodePtr pnodeNext;
  383. ParseNodeVar * pnodeName;
  384. IdentPtr pid;
  385. LPCOLESTR hint;
  386. uint32 hintLength;
  387. uint32 hintOffset;
  388. bool isNameIdentifierRef;
  389. bool nestedFuncEscapes;
  390. ParseNodeBlock * pnodeScopes;
  391. ParseNodeBlock * pnodeBodyScope;
  392. ParseNodePtr pnodeParams;
  393. ParseNodePtr pnodeVars;
  394. ParseNodePtr pnodeBody;
  395. ParseNodeVar * pnodeRest;
  396. FuncInfo *funcInfo; // function information gathered during byte code generation
  397. Scope *scope;
  398. uint nestedCount; // Nested function count (valid until children have been processed)
  399. uint nestedIndex; // Index within the parent function (Used by ByteCodeGenerator)
  400. uint16 firstDefaultArg; // Position of the first default argument, if any
  401. FncFlags fncFlags;
  402. int32 astSize;
  403. size_t cbMin; // Min an Lim UTF8 offsets.
  404. size_t cbLim;
  405. ULONG lineNumber; // Line number relative to the current source buffer of the function declaration.
  406. ULONG columnNumber; // Column number of the declaration.
  407. Js::LocalFunctionId functionId;
  408. #if DBG
  409. Js::LocalFunctionId deferredParseNextFunctionId;
  410. #endif
  411. RestorePoint *pRestorePoint;
  412. DeferredFunctionStub *deferredStub;
  413. IdentPtrSet *capturedNames;
  414. bool canBeDeferred;
  415. bool isBodyAndParamScopeMerged; // Indicates whether the param scope and the body scope of the function can be merged together or not.
  416. // We cannot merge both scopes together if there is any closure capture or eval is present in the param scope.
  417. Js::RegSlot homeObjLocation; // Stores the RegSlot from where the home object needs to be copied
  418. static const int32 MaxStackClosureAST = 800000;
  419. SuperRestrictionState::State superRestrictionState;
  420. static bool CanBeRedeferred(FncFlags flags) { return !(flags & (kFunctionIsGenerator | kFunctionIsAsync)); }
  421. private:
  422. void SetFlags(uint flags, bool set)
  423. {
  424. if (set)
  425. {
  426. fncFlags = (FncFlags)(fncFlags | flags);
  427. }
  428. else
  429. {
  430. fncFlags = (FncFlags)(fncFlags & ~flags);
  431. }
  432. }
  433. bool HasFlags(uint flags) const
  434. {
  435. return (fncFlags & flags) == flags;
  436. }
  437. bool HasAnyFlags(uint flags) const
  438. {
  439. return (fncFlags & flags) != 0;
  440. }
  441. bool HasNoFlags(uint flags) const
  442. {
  443. return (fncFlags & flags) == 0;
  444. }
  445. public:
  446. void ClearFlags()
  447. {
  448. fncFlags = kFunctionNone;
  449. canBeDeferred = false;
  450. isBodyAndParamScopeMerged = true;
  451. }
  452. void SetAsmjsMode(bool set = true) { SetFlags(kFunctionAsmjsMode, set); }
  453. void SetCallsEval(bool set = true) { SetFlags(kFunctionCallsEval, set); }
  454. void SetChildCallsEval(bool set = true) { SetFlags(kFunctionChildCallsEval, set); }
  455. void SetDeclaration(bool set = true) { SetFlags(kFunctionDeclaration, set); }
  456. void SetHasDefaultArguments(bool set = true) { SetFlags(kFunctionHasDefaultArguments, set); }
  457. void SetHasDestructuredParams(bool set = true) { SetFlags(kFunctionHasDestructuredParams, set); }
  458. void SetHasHeapArguments(bool set = true) { SetFlags(kFunctionHasHeapArguments, set); }
  459. void SetHasAnyWriteToFormals(bool set = true) { SetFlags((uint)kFunctionHasAnyWriteToFormals, set); }
  460. void SetHasNonSimpleParameterList(bool set = true) { SetFlags(kFunctionHasNonSimpleParameterList, set); }
  461. void SetHasNonThisStmt(bool set = true) { SetFlags(kFunctionHasNonThisStmt, set); }
  462. void SetHasReferenceableBuiltInArguments(bool set = true) { SetFlags(kFunctionHasReferenceableBuiltInArguments, set); }
  463. void SetHasSuperReference(bool set = true) { SetFlags(kFunctionHasSuperReference, set); }
  464. void SetHasDirectSuper(bool set = true) { SetFlags(kFunctionHasDirectSuper, set); }
  465. void SetHasWithStmt(bool set = true) { SetFlags(kFunctionHasWithStmt, set); }
  466. void SetIsAccessor(bool set = true) { SetFlags(kFunctionIsAccessor, set); }
  467. void SetIsAsync(bool set = true) { SetFlags(kFunctionIsAsync, set); }
  468. void SetIsClassConstructor(bool set = true) { SetFlags(kFunctionIsClassConstructor, set); }
  469. void SetIsBaseClassConstructor(bool set = true) { SetFlags(kFunctionIsBaseClassConstructor, set); }
  470. void SetIsClassMember(bool set = true) { SetFlags(kFunctionIsClassMember, set); }
  471. void SetIsGeneratedDefault(bool set = true) { SetFlags(kFunctionIsGeneratedDefault, set); }
  472. void SetIsGenerator(bool set = true) { SetFlags(kFunctionIsGenerator, set); }
  473. void SetIsLambda(bool set = true) { SetFlags(kFunctionIsLambda, set); }
  474. void SetIsMethod(bool set = true) { SetFlags(kFunctionIsMethod, set); }
  475. void SetIsStaticMember(bool set = true) { SetFlags(kFunctionIsStaticMember, set); }
  476. void SetNested(bool set = true) { SetFlags(kFunctionNested, set); }
  477. void SetStrictMode(bool set = true) { SetFlags(kFunctionStrictMode, set); }
  478. void SetIsModule(bool set = true) { SetFlags(kFunctionIsModule, set); }
  479. void SetHasComputedName(bool set = true) { SetFlags(kFunctionHasComputedName, set); }
  480. void SetHasHomeObj(bool set = true) { SetFlags(kFunctionHasHomeObj, set); }
  481. void SetUsesArguments(bool set = true) { SetFlags(kFunctionUsesArguments, set); }
  482. void SetIsDefaultModuleExport(bool set = true) { SetFlags(kFunctionIsDefaultModuleExport, set); }
  483. void SetIsDeclaredInParamScope(bool set = true) { SetFlags(kFunctionIsDeclaredInParamScope, set); }
  484. void SetNestedFuncEscapes(bool set = true) { nestedFuncEscapes = set; }
  485. void SetCanBeDeferred(bool set = true) { canBeDeferred = set; }
  486. void ResetBodyAndParamScopeMerged() { isBodyAndParamScopeMerged = false; }
  487. void SetHomeObjLocation(Js::RegSlot location) { this->homeObjLocation = location; }
  488. bool CallsEval() const { return HasFlags(kFunctionCallsEval); }
  489. bool ChildCallsEval() const { return HasFlags(kFunctionChildCallsEval); }
  490. bool GetArgumentsObjectEscapes() const { return HasFlags(kFunctionHasHeapArguments); }
  491. bool GetAsmjsMode() const { return HasFlags(kFunctionAsmjsMode); }
  492. bool GetStrictMode() const { return HasFlags(kFunctionStrictMode); }
  493. bool HasDefaultArguments() const { return HasFlags(kFunctionHasDefaultArguments); }
  494. bool HasDestructuredParams() const { return HasFlags(kFunctionHasDestructuredParams); }
  495. bool HasHeapArguments() const { return true; /* HasFlags(kFunctionHasHeapArguments); Disabling stack arguments. Always return HeapArguments as True */ }
  496. bool HasAnyWriteToFormals() const { return HasFlags((uint)kFunctionHasAnyWriteToFormals); }
  497. bool HasOnlyThisStmts() const { return !HasFlags(kFunctionHasNonThisStmt); }
  498. bool HasReferenceableBuiltInArguments() const { return HasFlags(kFunctionHasReferenceableBuiltInArguments); }
  499. bool HasSuperReference() const { return HasFlags(kFunctionHasSuperReference); }
  500. bool HasDirectSuper() const { return HasFlags(kFunctionHasDirectSuper); }
  501. bool HasNonSimpleParameterList() { return HasFlags(kFunctionHasNonSimpleParameterList); }
  502. bool HasWithStmt() const { return HasFlags(kFunctionHasWithStmt); }
  503. bool IsAccessor() const { return HasFlags(kFunctionIsAccessor); }
  504. bool IsAsync() const { return HasFlags(kFunctionIsAsync); }
  505. bool IsConstructor() const { return HasNoFlags(kFunctionIsAsync|kFunctionIsLambda|kFunctionIsAccessor); }
  506. bool IsClassConstructor() const { return HasFlags(kFunctionIsClassConstructor); }
  507. bool IsBaseClassConstructor() const { return HasFlags(kFunctionIsBaseClassConstructor); }
  508. bool IsDerivedClassConstructor() const { return IsClassConstructor() && !IsBaseClassConstructor(); }
  509. bool IsClassMember() const { return HasFlags(kFunctionIsClassMember); }
  510. bool IsDeclaration() const { return HasFlags(kFunctionDeclaration); }
  511. bool IsGeneratedDefault() const { return HasFlags(kFunctionIsGeneratedDefault); }
  512. bool IsGenerator() const { return HasFlags(kFunctionIsGenerator); }
  513. bool IsCoroutine() const { return HasAnyFlags(kFunctionIsGenerator | kFunctionIsAsync); }
  514. bool IsLambda() const { return HasFlags(kFunctionIsLambda); }
  515. bool IsMethod() const { return HasFlags(kFunctionIsMethod); }
  516. bool IsNested() const { return HasFlags(kFunctionNested); }
  517. bool IsStaticMember() const { return HasFlags(kFunctionIsStaticMember); }
  518. bool IsModule() const { return HasFlags(kFunctionIsModule); }
  519. bool HasComputedName() const { return HasFlags(kFunctionHasComputedName); }
  520. bool HasHomeObj() const { return HasFlags(kFunctionHasHomeObj); }
  521. bool UsesArguments() const { return HasFlags(kFunctionUsesArguments); }
  522. bool IsDefaultModuleExport() const { return HasFlags(kFunctionIsDefaultModuleExport); }
  523. bool IsDeclaredInParamScope() const { return HasFlags(kFunctionIsDeclaredInParamScope); }
  524. bool NestedFuncEscapes() const { return nestedFuncEscapes; }
  525. bool CanBeDeferred() const { return canBeDeferred; }
  526. bool IsBodyAndParamScopeMerged() { return isBodyAndParamScopeMerged; }
  527. Js::RegSlot GetHomeObjLocation() const { return homeObjLocation; }
  528. // Only allow the normal functions to be asm.js
  529. bool IsAsmJsAllowed() const { return (fncFlags & ~(
  530. kFunctionAsmjsMode |
  531. kFunctionNested |
  532. kFunctionDeclaration |
  533. kFunctionStrictMode |
  534. kFunctionHasReferenceableBuiltInArguments |
  535. kFunctionHasNonThisStmt |
  536. // todo:: we shouldn't accept kFunctionHasAnyWriteToFormals on the asm module, but it looks like a bug is setting that flag incorrectly
  537. kFunctionHasAnyWriteToFormals
  538. )) == 0; }
  539. size_t LengthInBytes()
  540. {
  541. return cbLim - cbMin;
  542. }
  543. Symbol *GetFuncSymbol();
  544. void SetFuncSymbol(Symbol *sym);
  545. ParseNodePtr GetParamScope() const;
  546. ParseNodePtr GetBodyScope() const;
  547. ParseNodePtr GetTopLevelScope() const
  548. {
  549. // Top level scope will be the same for knopProg and knopFncDecl.
  550. return GetParamScope();
  551. }
  552. template<typename Fn>
  553. void MapContainerScopes(Fn fn)
  554. {
  555. fn(this->pnodeScopes->pnodeScopes);
  556. if (this->pnodeBodyScope != nullptr)
  557. {
  558. fn(this->pnodeBodyScope->pnodeScopes);
  559. }
  560. }
  561. IdentPtrSet* EnsureCapturedNames(ArenaAllocator* alloc);
  562. IdentPtrSet* GetCapturedNames();
  563. bool HasAnyCapturedNames();
  564. DISABLE_SELF_CAST(ParseNodeFnc);
  565. };
  566. // class declaration
  567. class ParseNodeClass : public ParseNode
  568. {
  569. public:
  570. ParseNodeClass(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  571. ParseNodeVar * pnodeName;
  572. ParseNodeVar * pnodeDeclName;
  573. ParseNodeBlock * pnodeBlock;
  574. ParseNodeFnc * pnodeConstructor;
  575. ParseNodePtr pnodeMembers;
  576. ParseNodePtr pnodeStaticMembers;
  577. ParseNodePtr pnodeExtends;
  578. bool isDefaultModuleExport;
  579. void SetIsDefaultModuleExport(bool set) { isDefaultModuleExport = set; }
  580. bool IsDefaultModuleExport() const { return isDefaultModuleExport; }
  581. DISABLE_SELF_CAST(ParseNodeClass);
  582. };
  583. // export default expr
  584. class ParseNodeExportDefault : public ParseNode
  585. {
  586. public:
  587. ParseNodeExportDefault(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  588. ParseNodePtr pnodeExpr;
  589. DISABLE_SELF_CAST(ParseNodeExportDefault);
  590. };
  591. // string template declaration
  592. class ParseNodeStrTemplate : public ParseNode
  593. {
  594. public:
  595. ParseNodeStrTemplate(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  596. ParseNodePtr pnodeStringLiterals;
  597. ParseNodePtr pnodeStringRawLiterals;
  598. ParseNodePtr pnodeSubstitutionExpressions;
  599. uint16 countStringLiterals;
  600. BYTE isTaggedTemplate:1;
  601. DISABLE_SELF_CAST(ParseNodeStrTemplate);
  602. };
  603. // global program
  604. class ParseNodeProg : public ParseNodeFnc
  605. {
  606. public:
  607. ParseNodeProg(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  608. ParseNodePtr pnodeLastValStmt; // Used by ByteCodeGenerator
  609. bool m_UsesArgumentsAtGlobal;
  610. DISABLE_SELF_CAST(ParseNodeProg);
  611. };
  612. // global module
  613. class ParseNodeModule : public ParseNodeProg
  614. {
  615. public:
  616. ParseNodeModule(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  617. ModuleImportOrExportEntryList* localExportEntries;
  618. ModuleImportOrExportEntryList* indirectExportEntries;
  619. ModuleImportOrExportEntryList* starExportEntries;
  620. ModuleImportOrExportEntryList* importEntries;
  621. IdentPtrList* requestedModules;
  622. DISABLE_SELF_CAST(ParseNodeModule);
  623. };
  624. // function call
  625. class ParseNodeCall : public ParseNode
  626. {
  627. public:
  628. ParseNodeCall(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNodePtr pnodeTarget, ParseNodePtr pnodeArgs);
  629. ParseNodePtr pnodeTarget;
  630. ParseNodePtr pnodeArgs;
  631. uint16 argCount;
  632. uint16 spreadArgCount;
  633. BYTE callOfConstants : 1;
  634. BYTE isApplyCall : 1;
  635. BYTE isEvalCall : 1;
  636. BYTE isSuperCall : 1;
  637. BYTE hasDestructuring : 1;
  638. DISABLE_SELF_CAST(ParseNodeCall);
  639. };
  640. // base for statement nodes
  641. class ParseNodeStmt : public ParseNode
  642. {
  643. public:
  644. ParseNodeStmt(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  645. ParseNodeStmt * pnodeOuter;
  646. // Set by parsing code, used by code gen.
  647. uint grfnop;
  648. // Needed for byte code gen.
  649. Js::ByteCodeLabel breakLabel;
  650. Js::ByteCodeLabel continueLabel;
  651. bool emitLabels;
  652. DISABLE_SELF_CAST(ParseNodeStmt);
  653. };
  654. // block { }
  655. class ParseNodeBlock : public ParseNodeStmt
  656. {
  657. public:
  658. ParseNodeBlock(charcount_t ichMin, charcount_t ichLim, int blockId, PnodeBlockType blockType);
  659. ParseNodePtr pnodeStmt;
  660. ParseNodePtr pnodeLastValStmt;
  661. ParseNodePtr pnodeLexVars;
  662. ParseNodePtr pnodeScopes;
  663. ParseNodePtr pnodeNext;
  664. Scope *scope;
  665. ParseNodeBlock * enclosingBlock;
  666. int blockId;
  667. PnodeBlockType blockType:2;
  668. BYTE callsEval:1;
  669. BYTE childCallsEval:1;
  670. void SetCallsEval(bool does) { callsEval = does; }
  671. bool GetCallsEval() const { return callsEval; }
  672. void SetChildCallsEval(bool does) { childCallsEval = does; }
  673. bool GetChildCallsEval() const { return childCallsEval; }
  674. void SetEnclosingBlock(ParseNodeBlock * pnode) { enclosingBlock = pnode; }
  675. ParseNodeBlock * GetEnclosingBlock() const { return enclosingBlock; }
  676. bool HasBlockScopedContent() const;
  677. DISABLE_SELF_CAST(ParseNodeBlock);
  678. };
  679. // break and continue
  680. class ParseNodeJump : public ParseNodeStmt
  681. {
  682. public:
  683. ParseNodeJump(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  684. ParseNodeStmt * pnodeTarget;
  685. bool hasExplicitTarget;
  686. DISABLE_SELF_CAST(ParseNodeJump);
  687. };
  688. // base for loop nodes
  689. class ParseNodeLoop : public ParseNodeStmt
  690. {
  691. public:
  692. ParseNodeLoop(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  693. // Needed for byte code gen
  694. uint loopId;
  695. DISABLE_SELF_CAST(ParseNodeLoop);
  696. };
  697. // while and do-while loops
  698. class ParseNodeWhile : public ParseNodeLoop
  699. {
  700. public:
  701. ParseNodeWhile(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  702. ParseNodePtr pnodeCond;
  703. ParseNodePtr pnodeBody;
  704. DISABLE_SELF_CAST(ParseNodeWhile);
  705. };
  706. // with
  707. class ParseNodeWith : public ParseNodeStmt
  708. {
  709. public:
  710. ParseNodeWith(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  711. ParseNodePtr pnodeObj;
  712. ParseNodePtr pnodeBody;
  713. ParseNodePtr pnodeScopes;
  714. ParseNodePtr pnodeNext;
  715. Scope *scope;
  716. DISABLE_SELF_CAST(ParseNodeWith);
  717. };
  718. // Destructure pattern for function/catch parameter
  719. class ParseNodeParamPattern : public ParseNodeUni
  720. {
  721. public:
  722. ParseNodeParamPattern(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  723. ParseNodePtr pnodeNext;
  724. Js::RegSlot location;
  725. DISABLE_SELF_CAST(ParseNodeParamPattern);
  726. };
  727. // if
  728. class ParseNodeIf : public ParseNodeStmt
  729. {
  730. public:
  731. ParseNodeIf(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  732. ParseNodePtr pnodeCond;
  733. ParseNodePtr pnodeTrue;
  734. ParseNodePtr pnodeFalse;
  735. DISABLE_SELF_CAST(ParseNodeIf);
  736. };
  737. // for-in loop
  738. class ParseNodeForInOrForOf : public ParseNodeLoop
  739. {
  740. public:
  741. ParseNodeForInOrForOf(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  742. ParseNodePtr pnodeObj;
  743. ParseNodePtr pnodeBody;
  744. ParseNodePtr pnodeLval;
  745. ParseNodeBlock * pnodeBlock;
  746. Js::RegSlot itemLocation;
  747. DISABLE_SELF_CAST(ParseNodeForInOrForOf);
  748. };
  749. // for loop
  750. class ParseNodeFor : public ParseNodeLoop
  751. {
  752. public:
  753. ParseNodeFor(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  754. ParseNodePtr pnodeCond;
  755. ParseNodePtr pnodeBody;
  756. ParseNodePtr pnodeInit;
  757. ParseNodePtr pnodeIncr;
  758. ParseNodeBlock * pnodeBlock;
  759. ParseNodeFor * pnodeInverted;
  760. DISABLE_SELF_CAST(ParseNodeFor);
  761. };
  762. // switch
  763. class ParseNodeSwitch : public ParseNodeStmt
  764. {
  765. public:
  766. ParseNodeSwitch(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  767. ParseNodePtr pnodeVal;
  768. ParseNodeCase * pnodeCases;
  769. ParseNodeCase * pnodeDefault;
  770. ParseNodeBlock * pnodeBlock;
  771. DISABLE_SELF_CAST(ParseNodeSwitch);
  772. };
  773. // switch case
  774. class ParseNodeCase : public ParseNodeStmt
  775. {
  776. public:
  777. ParseNodeCase(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  778. ParseNodeCase * pnodeNext;
  779. ParseNodePtr pnodeExpr; // nullptr for default
  780. ParseNodeBlock * pnodeBody;
  781. Js::ByteCodeLabel labelCase;
  782. DISABLE_SELF_CAST(ParseNodeCase);
  783. };
  784. // return [expr]
  785. class ParseNodeReturn : public ParseNodeStmt
  786. {
  787. public:
  788. ParseNodeReturn(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  789. ParseNodePtr pnodeExpr;
  790. DISABLE_SELF_CAST(ParseNodeReturn);
  791. };
  792. // try-catch-finally
  793. class ParseNodeTryFinally : public ParseNodeStmt
  794. {
  795. public:
  796. ParseNodeTryFinally(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  797. ParseNodeTry * pnodeTry;
  798. ParseNodeFinally * pnodeFinally;
  799. DISABLE_SELF_CAST(ParseNodeTryFinally);
  800. };
  801. // try-catch
  802. class ParseNodeTryCatch : public ParseNodeStmt
  803. {
  804. public:
  805. ParseNodeTryCatch(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  806. ParseNodeTry * pnodeTry;
  807. ParseNodeCatch * pnodeCatch;
  808. DISABLE_SELF_CAST(ParseNodeTryCatch);
  809. };
  810. // try-catch
  811. class ParseNodeTry : public ParseNodeStmt
  812. {
  813. public:
  814. ParseNodeTry(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  815. ParseNodePtr pnodeBody;
  816. DISABLE_SELF_CAST(ParseNodeTry);
  817. };
  818. // { catch(e : expr) {body} }
  819. class ParseNodeCatch : public ParseNodeStmt
  820. {
  821. public:
  822. ParseNodeCatch(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  823. ParseNodePtr GetParam() { return pnodeParam; }
  824. void SetParam(ParseNodeName * pnode) { pnodeParam = pnode; }
  825. void SetParam(ParseNodeParamPattern * pnode) { pnodeParam = pnode; }
  826. ParseNodePtr pnodeNext;
  827. private:
  828. ParseNode * pnodeParam; // Name or ParamPattern
  829. public:
  830. ParseNodePtr pnodeBody;
  831. ParseNodePtr pnodeScopes;
  832. Scope *scope;
  833. DISABLE_SELF_CAST(ParseNodeCatch);
  834. };
  835. // finally
  836. class ParseNodeFinally : public ParseNodeStmt
  837. {
  838. public:
  839. ParseNodeFinally(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  840. ParseNodePtr pnodeBody;
  841. DISABLE_SELF_CAST(ParseNodeFinally);
  842. };
  843. // special name like 'this'
  844. class ParseNodeSpecialName : public ParseNodeName
  845. {
  846. public:
  847. ParseNodeSpecialName(charcount_t ichMin, charcount_t ichLim, IdentPtr pid);
  848. bool isThis : 1;
  849. bool isSuper : 1;
  850. DISABLE_SELF_CAST(ParseNodeSpecialName);
  851. };
  852. // binary operator with super reference
  853. class ParseNodeSuperReference : public ParseNodeBin
  854. {
  855. public:
  856. ParseNodeSuperReference(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnode1, ParseNode * pnode2);
  857. ParseNodeSpecialName * pnodeThis;
  858. DISABLE_SELF_CAST(ParseNodeSuperReference);
  859. };
  860. // call node with super target
  861. class ParseNodeSuperCall : public ParseNodeCall
  862. {
  863. public:
  864. ParseNodeSuperCall(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnodeTarget, ParseNode * pnodeArgs);
  865. ParseNodeSpecialName * pnodeThis;
  866. ParseNodeSpecialName * pnodeNewTarget;
  867. DISABLE_SELF_CAST(ParseNodeSuperCall);
  868. };
  869. typedef ParseNode ParseNodeNone;
  870. template <OpCode nop> class OpCodeTrait;
  871. #define PTNODE(nop,sn,pc,nk,ok,json) \
  872. template<> \
  873. class OpCodeTrait<nop> \
  874. { \
  875. public: \
  876. typedef ParseNode##nk ParseNodeType; \
  877. static const bool AllowDefer = ((ok) & fnopAllowDefer) != 0; \
  878. };
  879. #include "ptlist.h"