ptree.h 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082
  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. // Free = 1 << 27,
  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 SetNestedFuncEscapes(bool set = true) { nestedFuncEscapes = set; }
  484. void SetCanBeDeferred(bool set = true) { canBeDeferred = set; }
  485. void ResetBodyAndParamScopeMerged() { isBodyAndParamScopeMerged = false; }
  486. void SetHomeObjLocation(Js::RegSlot location) { this->homeObjLocation = location; }
  487. bool CallsEval() const { return HasFlags(kFunctionCallsEval); }
  488. bool ChildCallsEval() const { return HasFlags(kFunctionChildCallsEval); }
  489. bool GetArgumentsObjectEscapes() const { return HasFlags(kFunctionHasHeapArguments); }
  490. bool GetAsmjsMode() const { return HasFlags(kFunctionAsmjsMode); }
  491. bool GetStrictMode() const { return HasFlags(kFunctionStrictMode); }
  492. bool HasDefaultArguments() const { return HasFlags(kFunctionHasDefaultArguments); }
  493. bool HasDestructuredParams() const { return HasFlags(kFunctionHasDestructuredParams); }
  494. bool HasHeapArguments() const { return true; /* HasFlags(kFunctionHasHeapArguments); Disabling stack arguments. Always return HeapArguments as True */ }
  495. bool HasAnyWriteToFormals() const { return HasFlags((uint)kFunctionHasAnyWriteToFormals); }
  496. bool HasOnlyThisStmts() const { return !HasFlags(kFunctionHasNonThisStmt); }
  497. bool HasReferenceableBuiltInArguments() const { return HasFlags(kFunctionHasReferenceableBuiltInArguments); }
  498. bool HasSuperReference() const { return HasFlags(kFunctionHasSuperReference); }
  499. bool HasDirectSuper() const { return HasFlags(kFunctionHasDirectSuper); }
  500. bool HasNonSimpleParameterList() { return HasFlags(kFunctionHasNonSimpleParameterList); }
  501. bool HasWithStmt() const { return HasFlags(kFunctionHasWithStmt); }
  502. bool IsAccessor() const { return HasFlags(kFunctionIsAccessor); }
  503. bool IsAsync() const { return HasFlags(kFunctionIsAsync); }
  504. bool IsConstructor() const { return HasNoFlags(kFunctionIsAsync|kFunctionIsLambda|kFunctionIsAccessor); }
  505. bool IsClassConstructor() const { return HasFlags(kFunctionIsClassConstructor); }
  506. bool IsBaseClassConstructor() const { return HasFlags(kFunctionIsBaseClassConstructor); }
  507. bool IsDerivedClassConstructor() const { return IsClassConstructor() && !IsBaseClassConstructor(); }
  508. bool IsClassMember() const { return HasFlags(kFunctionIsClassMember); }
  509. bool IsDeclaration() const { return HasFlags(kFunctionDeclaration); }
  510. bool IsGeneratedDefault() const { return HasFlags(kFunctionIsGeneratedDefault); }
  511. bool IsGenerator() const { return HasFlags(kFunctionIsGenerator); }
  512. bool IsCoroutine() const { return HasAnyFlags(kFunctionIsGenerator | kFunctionIsAsync); }
  513. bool IsLambda() const { return HasFlags(kFunctionIsLambda); }
  514. bool IsMethod() const { return HasFlags(kFunctionIsMethod); }
  515. bool IsNested() const { return HasFlags(kFunctionNested); }
  516. bool IsStaticMember() const { return HasFlags(kFunctionIsStaticMember); }
  517. bool IsModule() const { return HasFlags(kFunctionIsModule); }
  518. bool HasComputedName() const { return HasFlags(kFunctionHasComputedName); }
  519. bool HasHomeObj() const { return HasFlags(kFunctionHasHomeObj); }
  520. bool UsesArguments() const { return HasFlags(kFunctionUsesArguments); }
  521. bool IsDefaultModuleExport() const { return HasFlags(kFunctionIsDefaultModuleExport); }
  522. bool NestedFuncEscapes() const { return nestedFuncEscapes; }
  523. bool CanBeDeferred() const { return canBeDeferred; }
  524. bool IsBodyAndParamScopeMerged() { return isBodyAndParamScopeMerged; }
  525. Js::RegSlot GetHomeObjLocation() const { return homeObjLocation; }
  526. // Only allow the normal functions to be asm.js
  527. bool IsAsmJsAllowed() const { return (fncFlags & ~(
  528. kFunctionAsmjsMode |
  529. kFunctionNested |
  530. kFunctionDeclaration |
  531. kFunctionStrictMode |
  532. kFunctionHasReferenceableBuiltInArguments |
  533. kFunctionHasNonThisStmt |
  534. // todo:: we shouldn't accept kFunctionHasAnyWriteToFormals on the asm module, but it looks like a bug is setting that flag incorrectly
  535. kFunctionHasAnyWriteToFormals
  536. )) == 0; }
  537. size_t LengthInBytes()
  538. {
  539. return cbLim - cbMin;
  540. }
  541. Symbol *GetFuncSymbol();
  542. void SetFuncSymbol(Symbol *sym);
  543. ParseNodePtr GetParamScope() const;
  544. ParseNodePtr GetBodyScope() const;
  545. ParseNodePtr GetTopLevelScope() const
  546. {
  547. // Top level scope will be the same for knopProg and knopFncDecl.
  548. return GetParamScope();
  549. }
  550. template<typename Fn>
  551. void MapContainerScopes(Fn fn)
  552. {
  553. fn(this->pnodeScopes->pnodeScopes);
  554. if (this->pnodeBodyScope != nullptr)
  555. {
  556. fn(this->pnodeBodyScope->pnodeScopes);
  557. }
  558. }
  559. IdentPtrSet* EnsureCapturedNames(ArenaAllocator* alloc);
  560. IdentPtrSet* GetCapturedNames();
  561. bool HasAnyCapturedNames();
  562. DISABLE_SELF_CAST(ParseNodeFnc);
  563. };
  564. // class declaration
  565. class ParseNodeClass : public ParseNode
  566. {
  567. public:
  568. ParseNodeClass(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  569. ParseNodeVar * pnodeName;
  570. ParseNodeVar * pnodeDeclName;
  571. ParseNodeBlock * pnodeBlock;
  572. ParseNodeFnc * pnodeConstructor;
  573. ParseNodePtr pnodeMembers;
  574. ParseNodePtr pnodeStaticMembers;
  575. ParseNodePtr pnodeExtends;
  576. bool isDefaultModuleExport;
  577. void SetIsDefaultModuleExport(bool set) { isDefaultModuleExport = set; }
  578. bool IsDefaultModuleExport() const { return isDefaultModuleExport; }
  579. DISABLE_SELF_CAST(ParseNodeClass);
  580. };
  581. // export default expr
  582. class ParseNodeExportDefault : public ParseNode
  583. {
  584. public:
  585. ParseNodeExportDefault(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  586. ParseNodePtr pnodeExpr;
  587. DISABLE_SELF_CAST(ParseNodeExportDefault);
  588. };
  589. // string template declaration
  590. class ParseNodeStrTemplate : public ParseNode
  591. {
  592. public:
  593. ParseNodeStrTemplate(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  594. ParseNodePtr pnodeStringLiterals;
  595. ParseNodePtr pnodeStringRawLiterals;
  596. ParseNodePtr pnodeSubstitutionExpressions;
  597. uint16 countStringLiterals;
  598. BYTE isTaggedTemplate:1;
  599. DISABLE_SELF_CAST(ParseNodeStrTemplate);
  600. };
  601. // global program
  602. class ParseNodeProg : public ParseNodeFnc
  603. {
  604. public:
  605. ParseNodeProg(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  606. ParseNodePtr pnodeLastValStmt; // Used by ByteCodeGenerator
  607. bool m_UsesArgumentsAtGlobal;
  608. DISABLE_SELF_CAST(ParseNodeProg);
  609. };
  610. // global module
  611. class ParseNodeModule : public ParseNodeProg
  612. {
  613. public:
  614. ParseNodeModule(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  615. ModuleImportOrExportEntryList* localExportEntries;
  616. ModuleImportOrExportEntryList* indirectExportEntries;
  617. ModuleImportOrExportEntryList* starExportEntries;
  618. ModuleImportOrExportEntryList* importEntries;
  619. IdentPtrList* requestedModules;
  620. DISABLE_SELF_CAST(ParseNodeModule);
  621. };
  622. // function call
  623. class ParseNodeCall : public ParseNode
  624. {
  625. public:
  626. ParseNodeCall(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNodePtr pnodeTarget, ParseNodePtr pnodeArgs);
  627. ParseNodePtr pnodeTarget;
  628. ParseNodePtr pnodeArgs;
  629. uint16 argCount;
  630. uint16 spreadArgCount;
  631. BYTE callOfConstants : 1;
  632. BYTE isApplyCall : 1;
  633. BYTE isEvalCall : 1;
  634. BYTE isSuperCall : 1;
  635. BYTE hasDestructuring : 1;
  636. DISABLE_SELF_CAST(ParseNodeCall);
  637. };
  638. // base for statement nodes
  639. class ParseNodeStmt : public ParseNode
  640. {
  641. public:
  642. ParseNodeStmt(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  643. ParseNodeStmt * pnodeOuter;
  644. // Set by parsing code, used by code gen.
  645. uint grfnop;
  646. // Needed for byte code gen.
  647. Js::ByteCodeLabel breakLabel;
  648. Js::ByteCodeLabel continueLabel;
  649. bool emitLabels;
  650. DISABLE_SELF_CAST(ParseNodeStmt);
  651. };
  652. // block { }
  653. class ParseNodeBlock : public ParseNodeStmt
  654. {
  655. public:
  656. ParseNodeBlock(charcount_t ichMin, charcount_t ichLim, int blockId, PnodeBlockType blockType);
  657. ParseNodePtr pnodeStmt;
  658. ParseNodePtr pnodeLastValStmt;
  659. ParseNodePtr pnodeLexVars;
  660. ParseNodePtr pnodeScopes;
  661. ParseNodePtr pnodeNext;
  662. Scope *scope;
  663. ParseNodeBlock * enclosingBlock;
  664. int blockId;
  665. PnodeBlockType blockType:2;
  666. BYTE callsEval:1;
  667. BYTE childCallsEval:1;
  668. void SetCallsEval(bool does) { callsEval = does; }
  669. bool GetCallsEval() const { return callsEval; }
  670. void SetChildCallsEval(bool does) { childCallsEval = does; }
  671. bool GetChildCallsEval() const { return childCallsEval; }
  672. void SetEnclosingBlock(ParseNodeBlock * pnode) { enclosingBlock = pnode; }
  673. ParseNodeBlock * GetEnclosingBlock() const { return enclosingBlock; }
  674. bool HasBlockScopedContent() const;
  675. DISABLE_SELF_CAST(ParseNodeBlock);
  676. };
  677. // break and continue
  678. class ParseNodeJump : public ParseNodeStmt
  679. {
  680. public:
  681. ParseNodeJump(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  682. ParseNodeStmt * pnodeTarget;
  683. bool hasExplicitTarget;
  684. DISABLE_SELF_CAST(ParseNodeJump);
  685. };
  686. // base for loop nodes
  687. class ParseNodeLoop : public ParseNodeStmt
  688. {
  689. public:
  690. ParseNodeLoop(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  691. // Needed for byte code gen
  692. uint loopId;
  693. DISABLE_SELF_CAST(ParseNodeLoop);
  694. };
  695. // while and do-while loops
  696. class ParseNodeWhile : public ParseNodeLoop
  697. {
  698. public:
  699. ParseNodeWhile(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  700. ParseNodePtr pnodeCond;
  701. ParseNodePtr pnodeBody;
  702. DISABLE_SELF_CAST(ParseNodeWhile);
  703. };
  704. // with
  705. class ParseNodeWith : public ParseNodeStmt
  706. {
  707. public:
  708. ParseNodeWith(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  709. ParseNodePtr pnodeObj;
  710. ParseNodePtr pnodeBody;
  711. ParseNodePtr pnodeScopes;
  712. ParseNodePtr pnodeNext;
  713. Scope *scope;
  714. DISABLE_SELF_CAST(ParseNodeWith);
  715. };
  716. // Destructure pattern for function/catch parameter
  717. class ParseNodeParamPattern : public ParseNodeUni
  718. {
  719. public:
  720. ParseNodeParamPattern(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  721. ParseNodePtr pnodeNext;
  722. Js::RegSlot location;
  723. DISABLE_SELF_CAST(ParseNodeParamPattern);
  724. };
  725. // if
  726. class ParseNodeIf : public ParseNodeStmt
  727. {
  728. public:
  729. ParseNodeIf(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  730. ParseNodePtr pnodeCond;
  731. ParseNodePtr pnodeTrue;
  732. ParseNodePtr pnodeFalse;
  733. DISABLE_SELF_CAST(ParseNodeIf);
  734. };
  735. // for-in loop
  736. class ParseNodeForInOrForOf : public ParseNodeLoop
  737. {
  738. public:
  739. ParseNodeForInOrForOf(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  740. ParseNodePtr pnodeObj;
  741. ParseNodePtr pnodeBody;
  742. ParseNodePtr pnodeLval;
  743. ParseNodeBlock * pnodeBlock;
  744. Js::RegSlot itemLocation;
  745. DISABLE_SELF_CAST(ParseNodeForInOrForOf);
  746. };
  747. // for loop
  748. class ParseNodeFor : public ParseNodeLoop
  749. {
  750. public:
  751. ParseNodeFor(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  752. ParseNodePtr pnodeCond;
  753. ParseNodePtr pnodeBody;
  754. ParseNodePtr pnodeInit;
  755. ParseNodePtr pnodeIncr;
  756. ParseNodeBlock * pnodeBlock;
  757. ParseNodeFor * pnodeInverted;
  758. DISABLE_SELF_CAST(ParseNodeFor);
  759. };
  760. // switch
  761. class ParseNodeSwitch : public ParseNodeStmt
  762. {
  763. public:
  764. ParseNodeSwitch(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  765. ParseNodePtr pnodeVal;
  766. ParseNodeCase * pnodeCases;
  767. ParseNodeCase * pnodeDefault;
  768. ParseNodeBlock * pnodeBlock;
  769. DISABLE_SELF_CAST(ParseNodeSwitch);
  770. };
  771. // switch case
  772. class ParseNodeCase : public ParseNodeStmt
  773. {
  774. public:
  775. ParseNodeCase(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  776. ParseNodeCase * pnodeNext;
  777. ParseNodePtr pnodeExpr; // nullptr for default
  778. ParseNodeBlock * pnodeBody;
  779. Js::ByteCodeLabel labelCase;
  780. DISABLE_SELF_CAST(ParseNodeCase);
  781. };
  782. // return [expr]
  783. class ParseNodeReturn : public ParseNodeStmt
  784. {
  785. public:
  786. ParseNodeReturn(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  787. ParseNodePtr pnodeExpr;
  788. DISABLE_SELF_CAST(ParseNodeReturn);
  789. };
  790. // try-catch-finally
  791. class ParseNodeTryFinally : public ParseNodeStmt
  792. {
  793. public:
  794. ParseNodeTryFinally(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  795. ParseNodeTry * pnodeTry;
  796. ParseNodeFinally * pnodeFinally;
  797. DISABLE_SELF_CAST(ParseNodeTryFinally);
  798. };
  799. // try-catch
  800. class ParseNodeTryCatch : public ParseNodeStmt
  801. {
  802. public:
  803. ParseNodeTryCatch(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  804. ParseNodeTry * pnodeTry;
  805. ParseNodeCatch * pnodeCatch;
  806. DISABLE_SELF_CAST(ParseNodeTryCatch);
  807. };
  808. // try-catch
  809. class ParseNodeTry : public ParseNodeStmt
  810. {
  811. public:
  812. ParseNodeTry(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  813. ParseNodePtr pnodeBody;
  814. DISABLE_SELF_CAST(ParseNodeTry);
  815. };
  816. // { catch(e : expr) {body} }
  817. class ParseNodeCatch : public ParseNodeStmt
  818. {
  819. public:
  820. ParseNodeCatch(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  821. ParseNodePtr GetParam() { return pnodeParam; }
  822. void SetParam(ParseNodeName * pnode) { pnodeParam = pnode; }
  823. void SetParam(ParseNodeParamPattern * pnode) { pnodeParam = pnode; }
  824. ParseNodePtr pnodeNext;
  825. private:
  826. ParseNode * pnodeParam; // Name or ParamPattern
  827. public:
  828. ParseNodePtr pnodeBody;
  829. ParseNodePtr pnodeScopes;
  830. Scope *scope;
  831. DISABLE_SELF_CAST(ParseNodeCatch);
  832. };
  833. // finally
  834. class ParseNodeFinally : public ParseNodeStmt
  835. {
  836. public:
  837. ParseNodeFinally(OpCode nop, charcount_t ichMin, charcount_t ichLim);
  838. ParseNodePtr pnodeBody;
  839. DISABLE_SELF_CAST(ParseNodeFinally);
  840. };
  841. // special name like 'this'
  842. class ParseNodeSpecialName : public ParseNodeName
  843. {
  844. public:
  845. ParseNodeSpecialName(charcount_t ichMin, charcount_t ichLim, IdentPtr pid);
  846. bool isThis : 1;
  847. bool isSuper : 1;
  848. DISABLE_SELF_CAST(ParseNodeSpecialName);
  849. };
  850. // binary operator with super reference
  851. class ParseNodeSuperReference : public ParseNodeBin
  852. {
  853. public:
  854. ParseNodeSuperReference(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnode1, ParseNode * pnode2);
  855. ParseNodeSpecialName * pnodeThis;
  856. DISABLE_SELF_CAST(ParseNodeSuperReference);
  857. };
  858. // call node with super target
  859. class ParseNodeSuperCall : public ParseNodeCall
  860. {
  861. public:
  862. ParseNodeSuperCall(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnodeTarget, ParseNode * pnodeArgs);
  863. ParseNodeSpecialName * pnodeThis;
  864. ParseNodeSpecialName * pnodeNewTarget;
  865. DISABLE_SELF_CAST(ParseNodeSuperCall);
  866. };
  867. typedef ParseNode ParseNodeNone;
  868. template <OpCode nop> class OpCodeTrait;
  869. #define PTNODE(nop,sn,pc,nk,ok,json) \
  870. template<> \
  871. class OpCodeTrait<nop> \
  872. { \
  873. public: \
  874. typedef ParseNode##nk ParseNodeType; \
  875. static const bool AllowDefer = ((ok) & fnopAllowDefer) != 0; \
  876. };
  877. #include "ptlist.h"