| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101 |
- //-------------------------------------------------------------------------------------------------------
- // Copyright (C) Microsoft. All rights reserved.
- // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
- //-------------------------------------------------------------------------------------------------------
- #pragma once
- struct Ident;
- typedef Ident *IdentPtr;
- class Scope;
- /***************************************************************************
- Flags for classifying node operators.
- ***************************************************************************/
- const uint fnopNone = 0x0000;
- const uint fnopConst = 0x0001; // constant
- const uint fnopLeaf = 0x0002; // leaf
- const uint fnopUni = 0x0004; // unary
- const uint fnopBin = 0x0008; // binary
- const uint fnopRel = 0x0010; // relational
- const uint fnopAsg = 0x0020; // assignment
- const uint fnopBreak = 0x0040; // break can be used within this statement
- const uint fnopContinue = 0x0080; // continue can be used within this statement
- const uint fnopCleanup = 0x0100; // requires cleanup (eg, with or for-in).
- const uint fnopJump = 0x0200;
- const uint fnopNotExprStmt = 0x0400;
- const uint fnopBinList = 0x0800;
- const uint fnopExprMask = (fnopLeaf|fnopUni|fnopBin);
- const uint fnopAllowDefer = 0x1000; // allow to be created during defer parse
- /***************************************************************************
- Flags for classifying parse nodes.
- ***************************************************************************/
- enum PNodeFlags : ushort
- {
- fpnNone = 0x0000,
- // knopFncDecl nodes.
- 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
- fpnArguments_overriddenInParam = 0x0002, // function has a parameter named arguments
- fpnArguments_varDeclaration = 0x0004, // function has a var declaration named 'arguments', which may change the way an 'arguments' identifier is resolved
- // knopVarDecl nodes.
- fpnArguments = 0x0008,
- fpnHidden = 0x0010,
- // Statement nodes.
- fpnExplicitSemicolon = 0x0020, // statement terminated by an explicit semicolon
- fpnAutomaticSemicolon = 0x0040, // statement terminated by an automatic semicolon
- fpnMissingSemicolon = 0x0080, // statement missing terminating semicolon, and is not applicable for automatic semicolon insertion
- fpnDclList = 0x0100, // statement is a declaration list
- fpnSyntheticNode = 0x0200, // node is added by the parser or does it represent user code
- fpnIndexOperator = 0x0400, // dot operator is an optimization of an index operator
- fpnJumbStatement = 0x0800, // break or continue that was removed by error recovery
- // Unary/Binary nodes
- fpnCanFlattenConcatExpr = 0x1000, // the result of the binary operation can participate in concat N
- // Potentially overlapping traversal flags
- // These flags are set and cleared during a single node traversal and their values can be used in other node traversals.
- fpnMemberReference = 0x2000, // The node is a member reference symbol
- fpnCapturesSyms = 0x4000, // The node is a statement (or contains a sub-statement)
- // that captures symbols.
- fpnSpecialSymbol = 0x8000,
- };
- /***************************************************************************
- Data structs for ParseNodes.
- ***************************************************************************/
- class ParseNodeUni;
- class ParseNodeBin;
- class ParseNodeTri;
- class ParseNodeInt;
- class ParseNodeBigInt;
- class ParseNodeFloat;
- class ParseNodeRegExp;
- class ParseNodeStr;
- class ParseNodeName;
- class ParseNodeVar;
- class ParseNodeCall;
- class ParseNodeSuperCall;
- class ParseNodeSpecialName;
- class ParseNodeExportDefault;
- class ParseNodeStrTemplate;
- class ParseNodeSuperReference;
- class ParseNodeArrLit;
- class ParseNodeObjLit;
- class ParseNodeClass;
- class ParseNodeParamPattern;
- class ParseNodeStmt;
- class ParseNodeBlock;
- class ParseNodeJump;
- class ParseNodeWith;
- class ParseNodeIf;
- class ParseNodeSwitch;
- class ParseNodeCase;
- class ParseNodeReturn;
- class ParseNodeTryFinally;
- class ParseNodeTryCatch;
- class ParseNodeTry;
- class ParseNodeCatch;
- class ParseNodeFinally;
- class ParseNodeWhile;
- class ParseNodeFor;
- class ParseNodeForInOrForOf;
- class ParseNodeFnc;
- class ParseNodeProg;
- class ParseNodeModule;
- class ParseNode
- {
- public:
- ParseNode(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodeUni * AsParseNodeUni();
- ParseNodeBin * AsParseNodeBin();
- ParseNodeTri * AsParseNodeTri();
- ParseNodeInt * AsParseNodeInt();
- ParseNodeBigInt * AsParseNodeBigInt();
- ParseNodeFloat * AsParseNodeFloat();
- ParseNodeRegExp * AsParseNodeRegExp();
- ParseNodeVar * AsParseNodeVar();
- ParseNodeStr * AsParseNodeStr();
- ParseNodeName * AsParseNodeName();
- ParseNodeSpecialName * AsParseNodeSpecialName();
- ParseNodeExportDefault * AsParseNodeExportDefault();
- ParseNodeStrTemplate * AsParseNodeStrTemplate();
- ParseNodeSuperReference * AsParseNodeSuperReference();
- ParseNodeArrLit * AsParseNodeArrLit();
- ParseNodeObjLit * AsParseNodeObjLit();
- ParseNodeCall * AsParseNodeCall();
- ParseNodeSuperCall * AsParseNodeSuperCall();
- ParseNodeClass * AsParseNodeClass();
- ParseNodeParamPattern * AsParseNodeParamPattern();
- ParseNodeStmt * AsParseNodeStmt();
- ParseNodeBlock * AsParseNodeBlock();
- ParseNodeJump * AsParseNodeJump();
- ParseNodeWith * AsParseNodeWith();
- ParseNodeIf * AsParseNodeIf();
- ParseNodeSwitch * AsParseNodeSwitch();
- ParseNodeCase * AsParseNodeCase();
- ParseNodeReturn * AsParseNodeReturn();
- ParseNodeTryFinally * AsParseNodeTryFinally();
- ParseNodeTryCatch * AsParseNodeTryCatch();
- ParseNodeTry * AsParseNodeTry();
- ParseNodeCatch * AsParseNodeCatch();
- ParseNodeFinally * AsParseNodeFinally();
- ParseNodeWhile * AsParseNodeWhile();
- ParseNodeFor * AsParseNodeFor();
- ParseNodeForInOrForOf * AsParseNodeForInOrForOf();
- ParseNodeFnc * AsParseNodeFnc();
- ParseNodeProg * AsParseNodeProg();
- ParseNodeModule * AsParseNodeModule();
- static uint Grfnop(int nop)
- {
- Assert(nop < knopLim);
- return nop < knopLim ? mpnopgrfnop[nop] : fnopNone;
- }
- BOOL IsStatement()
- {
- return nop >= knopList || ((Grfnop(nop) & fnopAsg) != 0);
- }
- uint Grfnop(void)
- {
- Assert(nop < knopLim);
- return nop < knopLim ? mpnopgrfnop[nop] : fnopNone;
- }
- IdentPtr name();
- charcount_t LengthInCodepoints() const
- {
- return (this->ichLim - this->ichMin);
- }
- // This node is a function decl node and function has a var declaration named 'arguments',
- bool HasVarArguments() const
- {
- return ((nop == knopFncDecl) && (grfpn & PNodeFlags::fpnArguments_varDeclaration));
- }
- bool CapturesSyms() const
- {
- return (grfpn & PNodeFlags::fpnCapturesSyms) != 0;
- }
- void SetCapturesSyms()
- {
- grfpn |= PNodeFlags::fpnCapturesSyms;
- }
- bool IsInList() const { return this->isInList; }
- void SetIsInList() { this->isInList = true; }
- bool IsNotEscapedUse() const { return this->notEscapedUse; }
- void SetNotEscapedUse() { this->notEscapedUse = true; }
- bool CanFlattenConcatExpr() const { return !!(this->grfpn & PNodeFlags::fpnCanFlattenConcatExpr); }
- bool IsCallApplyTargetLoad() { return isCallApplyTargetLoad; }
- void SetIsCallApplyTargetLoad() { isCallApplyTargetLoad = true; }
- bool IsPatternDeclaration() { return isPatternDeclaration; }
- void SetIsPatternDeclaration() { isPatternDeclaration = true; }
- bool IsUserIdentifier();
- bool IsVarLetOrConst() const
- {
- return this->nop == knopVarDecl || this->nop == knopLetDecl || this->nop == knopConstDecl;
- }
- ParseNodePtr GetFormalNext();
- bool IsPattern() const
- {
- return nop == knopObjectPattern || nop == knopArrayPattern;
- }
- #if DBG_DUMP
- void Dump();
- #endif
- public:
- static const uint mpnopgrfnop[knopLim];
- OpCode nop;
- bool isUsed : 1; // indicates whether an expression such as x++ is used
- private:
- bool isInList : 1;
- // Use by byte code generator
- bool notEscapedUse : 1; // Currently, only used by child of knopComma
- bool isCallApplyTargetLoad : 1;
- // Use by bytecodegen to identify the current node is a destructuring pattern declaration node.
- bool isPatternDeclaration : 1;
- public:
- ushort grfpn;
- charcount_t ichMin; // start offset into the original source buffer
- charcount_t ichLim; // end offset into the original source buffer
- Js::RegSlot location;
- #ifdef EDIT_AND_CONTINUE
- ParseNodePtr parent;
- #endif
- };
- #define DISABLE_SELF_CAST(T) private: T * As##T()
- // unary operators
- class ParseNodeUni : public ParseNode
- {
- public:
- ParseNodeUni(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnode1);
- ParseNodePtr pnode1;
- DISABLE_SELF_CAST(ParseNodeUni);
- };
- // binary operators
- class ParseNodeBin : public ParseNode
- {
- public:
- ParseNodeBin(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnode1, ParseNode * pnode2);
- ParseNodePtr pnode1;
- ParseNodePtr pnode2;
- DISABLE_SELF_CAST(ParseNodeBin);
- };
- // ternary operator
- class ParseNodeTri : public ParseNode
- {
- public:
- ParseNodeTri(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodePtr pnode1;
- ParseNodePtr pnode2;
- ParseNodePtr pnode3;
- DISABLE_SELF_CAST(ParseNodeTri);
- };
- // integer constant
- class ParseNodeInt : public ParseNode
- {
- public:
- ParseNodeInt(charcount_t ichMin, charcount_t ichMax, int32 lw);
- int32 lw;
- DISABLE_SELF_CAST(ParseNodeInt);
- };
- // bigint constant
- class ParseNodeBigInt : public ParseNode
- {
- public:
- ParseNodeBigInt(charcount_t ichMin, charcount_t ichLim, IdentPtr pid);
- IdentPtr const pid;
- bool isNegative : 1;
- DISABLE_SELF_CAST(ParseNodeBigInt);
- };
- // double constant
- class ParseNodeFloat : public ParseNode
- {
- public:
- ParseNodeFloat(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- double dbl;
- bool maybeInt : 1;
- DISABLE_SELF_CAST(ParseNodeFloat);
- };
- class ParseNodeRegExp : public ParseNode
- {
- public:
- ParseNodeRegExp(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- UnifiedRegex::RegexPattern* regexPattern;
- uint regexPatternIndex;
- DISABLE_SELF_CAST(ParseNodeRegExp);
- };
- // identifier or string
- class ParseNodeStr : public ParseNode
- {
- public:
- ParseNodeStr(charcount_t ichMin, charcount_t ichLim, IdentPtr pid);
- IdentPtr const pid;
- DISABLE_SELF_CAST(ParseNodeStr);
- };
- class Symbol;
- struct PidRefStack;
- class ParseNodeName : public ParseNode
- {
- public:
- ParseNodeName(charcount_t ichMin, charcount_t ichLim, IdentPtr pid);
- IdentPtr const pid;
- private:
- Symbol **symRef;
- public:
- Symbol *sym;
- void SetSymRef(PidRefStack *ref);
- void ClearSymRef() { symRef = nullptr; }
- Symbol **GetSymRef() const { return symRef; }
- Js::PropertyId PropertyIdFromNameNode() const;
- bool IsSpecialName() { return isSpecialName; }
- DISABLE_SELF_CAST(ParseNodeName);
- protected:
- void SetIsSpecialName() { isSpecialName = true; }
- private:
- bool isSpecialName; // indicates a PnPid (knopName) is a special name like 'this' or 'super'
- };
- // variable declaration
- class ParseNodeVar : public ParseNode
- {
- public:
- ParseNodeVar(OpCode nop, charcount_t ichMin, charcount_t ichLim, IdentPtr name);
- ParseNodePtr pnodeNext;
- IdentPtr const pid;
- Symbol *sym;
- Symbol **symRef;
- ParseNodePtr pnodeInit;
- BOOLEAN isSwitchStmtDecl;
- BOOLEAN isBlockScopeFncDeclVar;
- DISABLE_SELF_CAST(ParseNodeVar);
- };
- // Array literal
- class ParseNodeArrLit : public ParseNodeUni
- {
- public:
- ParseNodeArrLit(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- uint count;
- uint spreadCount;
- BYTE arrayOfTaggedInts:1; // indicates that array initializer nodes are all tagged ints
- BYTE arrayOfInts:1; // indicates that array initializer nodes are all ints
- BYTE arrayOfNumbers:1; // indicates that array initializer nodes are all numbers
- BYTE hasMissingValues:1;
- DISABLE_SELF_CAST(ParseNodeArrLit);
- };
- class ParseNodeObjLit : public ParseNodeUni
- {
- public:
- ParseNodeObjLit(OpCode nop, charcount_t ichMin, charcount_t ichLim, uint staticCnt=0, uint computedCnt=0, bool rest=false);
- uint staticCount;
- uint computedCount;
- bool hasRest;
- DISABLE_SELF_CAST(ParseNodeObjLit);
- };
- class FuncInfo;
- enum PnodeBlockType : unsigned
- {
- Global,
- Function,
- Regular,
- Parameter
- };
- enum FncFlags : uint
- {
- kFunctionNone = 0,
- kFunctionNested = 1 << 0, // True if function is nested in another.
- kFunctionDeclaration = 1 << 1, // is this a declaration or an expression?
- kFunctionCallsEval = 1 << 2, // function uses eval
- kFunctionUsesArguments = 1 << 3, // function uses arguments
- kFunctionHasHeapArguments = 1 << 4, // function's "arguments" escape the scope
- kFunctionHasReferenceableBuiltInArguments = 1 << 5, // the built-in 'arguments' object is referenceable in the function
- kFunctionIsAccessor = 1 << 6, // function is a property getter or setter
- kFunctionHasNonThisStmt = 1 << 7,
- kFunctionStrictMode = 1 << 8,
- kFunctionHasDestructuredParams = 1 << 9,
- kFunctionIsModule = 1 << 10, // function is a module body
- kFunctionHasComputedName = 1 << 11,
- kFunctionHasWithStmt = 1 << 12, // function (or child) uses with
- kFunctionIsLambda = 1 << 13,
- kFunctionChildCallsEval = 1 << 14,
- kFunctionHasNonSimpleParameterList = 1 << 15,
- kFunctionHasSuperReference = 1 << 16,
- kFunctionIsMethod = 1 << 17,
- kFunctionIsClassConstructor = 1 << 18, // function is a class constructor
- kFunctionIsBaseClassConstructor = 1 << 19, // function is a base class constructor
- kFunctionIsClassMember = 1 << 20, // function is a class member
- kFunctionHasHomeObj = 1 << 21, // function has home object. Class or member functions need to have home obj.
- kFunctionIsGeneratedDefault = 1 << 22, // Is the function generated by us as a default (e.g. default class constructor)
- kFunctionHasDefaultArguments = 1 << 23, // Function has one or more ES6 default arguments
- kFunctionIsStaticMember = 1 << 24,
- kFunctionIsGenerator = 1 << 25, // Function is an ES6 generator function
- kFunctionAsmjsMode = 1 << 26,
- kFunctionIsDeclaredInParamScope = 1 << 27, // Function is declared in parameter scope (ex: inside default argument)
- kFunctionIsAsync = 1 << 28, // function is async
- kFunctionHasDirectSuper = 1 << 29, // super()
- kFunctionIsDefaultModuleExport = 1 << 30, // function is the default export of a module
- kFunctionHasAnyWriteToFormals = (uint)1 << 31 // To Track if there are any writes to formals.
- };
- struct RestorePoint;
- struct DeferredFunctionStub;
- namespace SuperRestrictionState {
- enum State {
- Disallowed = 0,
- CallAndPropertyAllowed = 1,
- PropertyAllowed = 2
- };
- }
- // function declaration
- class ParseNodeFnc : public ParseNode
- {
- public:
- ParseNodeFnc(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodePtr pnodeNext;
- ParseNodeVar * pnodeName;
- IdentPtr pid;
- LPCOLESTR hint;
- uint32 hintLength;
- uint32 hintOffset;
- ParseNodeBlock * pnodeScopes;
- ParseNodeBlock * pnodeBodyScope;
- ParseNodePtr pnodeParams;
- ParseNodePtr pnodeVars;
- ParseNodePtr pnodeBody;
- ParseNodePtr pnodeRest;
- FuncInfo *funcInfo; // function information gathered during byte code generation
- Scope *scope;
- uint nestedCount; // Nested function count (valid until children have been processed)
- uint nestedIndex; // Index within the parent function (Used by ByteCodeGenerator)
- FncFlags fncFlags;
- int32 astSize;
- size_t cbMin; // Min an Lim UTF8 offsets.
- size_t cbStringMin;
- size_t cbStringLim;
- size_t cbLim;
- ULONG lineNumber; // Line number relative to the current source buffer of the function declaration.
- ULONG columnNumber; // Column number of the declaration.
- Js::LocalFunctionId functionId;
- #if DBG
- Js::LocalFunctionId deferredParseNextFunctionId;
- #endif
- RestorePoint *pRestorePoint;
- DeferredFunctionStub *deferredStub;
- IdentPtrSet *capturedNames;
- uint16 firstDefaultArg; // Position of the first default argument, if any
- bool isNameIdentifierRef;
- bool nestedFuncEscapes;
- bool canBeDeferred;
- bool isBodyAndParamScopeMerged; // Indicates whether the param scope and the body scope of the function can be merged together or not.
- // We cannot merge both scopes together if there is any closure capture or eval is present in the param scope.
- Js::RegSlot homeObjLocation; // Stores the RegSlot from where the home object needs to be copied
- static const int32 MaxStackClosureAST = 800000;
- SuperRestrictionState::State superRestrictionState;
- static bool CanBeRedeferred(FncFlags flags) { return !(flags & (kFunctionIsGenerator | kFunctionIsAsync)); }
- private:
- void SetFlags(uint flags, bool set)
- {
- if (set)
- {
- fncFlags = (FncFlags)(fncFlags | flags);
- }
- else
- {
- fncFlags = (FncFlags)(fncFlags & ~flags);
- }
- }
- bool HasFlags(uint flags) const
- {
- return (fncFlags & flags) == flags;
- }
- bool HasAnyFlags(uint flags) const
- {
- return (fncFlags & flags) != 0;
- }
- bool HasNoFlags(uint flags) const
- {
- return (fncFlags & flags) == 0;
- }
- public:
- void ClearFlags()
- {
- fncFlags = kFunctionNone;
- canBeDeferred = false;
- isBodyAndParamScopeMerged = true;
- }
- void SetAsmjsMode(bool set = true) { SetFlags(kFunctionAsmjsMode, set); }
- void SetCallsEval(bool set = true) { SetFlags(kFunctionCallsEval, set); }
- void SetChildCallsEval(bool set = true) { SetFlags(kFunctionChildCallsEval, set); }
- void SetDeclaration(bool set = true) { SetFlags(kFunctionDeclaration, set); }
- void SetHasDefaultArguments(bool set = true) { SetFlags(kFunctionHasDefaultArguments, set); }
- void SetHasDestructuredParams(bool set = true) { SetFlags(kFunctionHasDestructuredParams, set); }
- void SetHasHeapArguments(bool set = true) { SetFlags(kFunctionHasHeapArguments, set); }
- void SetHasAnyWriteToFormals(bool set = true) { SetFlags((uint)kFunctionHasAnyWriteToFormals, set); }
- void SetHasNonSimpleParameterList(bool set = true) { SetFlags(kFunctionHasNonSimpleParameterList, set); }
- void SetHasNonThisStmt(bool set = true) { SetFlags(kFunctionHasNonThisStmt, set); }
- void SetHasReferenceableBuiltInArguments(bool set = true) { SetFlags(kFunctionHasReferenceableBuiltInArguments, set); }
- void SetHasSuperReference(bool set = true) { SetFlags(kFunctionHasSuperReference, set); }
- void SetHasDirectSuper(bool set = true) { SetFlags(kFunctionHasDirectSuper, set); }
- void SetHasWithStmt(bool set = true) { SetFlags(kFunctionHasWithStmt, set); }
- void SetIsAccessor(bool set = true) { SetFlags(kFunctionIsAccessor, set); }
- void SetIsAsync(bool set = true) { SetFlags(kFunctionIsAsync, set); }
- void SetIsClassConstructor(bool set = true) { SetFlags(kFunctionIsClassConstructor, set); }
- void SetIsBaseClassConstructor(bool set = true) { SetFlags(kFunctionIsBaseClassConstructor, set); }
- void SetIsClassMember(bool set = true) { SetFlags(kFunctionIsClassMember, set); }
- void SetIsGeneratedDefault(bool set = true) { SetFlags(kFunctionIsGeneratedDefault, set); }
- void SetIsGenerator(bool set = true) { SetFlags(kFunctionIsGenerator, set); }
- void SetIsLambda(bool set = true) { SetFlags(kFunctionIsLambda, set); }
- void SetIsMethod(bool set = true) { SetFlags(kFunctionIsMethod, set); }
- void SetIsStaticMember(bool set = true) { SetFlags(kFunctionIsStaticMember, set); }
- void SetNested(bool set = true) { SetFlags(kFunctionNested, set); }
- void SetStrictMode(bool set = true) { SetFlags(kFunctionStrictMode, set); }
- void SetIsModule(bool set = true) { SetFlags(kFunctionIsModule, set); }
- void SetHasComputedName(bool set = true) { SetFlags(kFunctionHasComputedName, set); }
- void SetHasHomeObj(bool set = true) { SetFlags(kFunctionHasHomeObj, set); }
- void SetUsesArguments(bool set = true) { SetFlags(kFunctionUsesArguments, set); }
- void SetIsDefaultModuleExport(bool set = true) { SetFlags(kFunctionIsDefaultModuleExport, set); }
- void SetIsDeclaredInParamScope(bool set = true) { SetFlags(kFunctionIsDeclaredInParamScope, set); }
- void SetNestedFuncEscapes(bool set = true) { nestedFuncEscapes = set; }
- void SetCanBeDeferred(bool set = true) { canBeDeferred = set; }
- void ResetBodyAndParamScopeMerged() { isBodyAndParamScopeMerged = false; }
- void SetHomeObjLocation(Js::RegSlot location) { this->homeObjLocation = location; }
- bool CallsEval() const { return HasFlags(kFunctionCallsEval); }
- bool ChildCallsEval() const { return HasFlags(kFunctionChildCallsEval); }
- bool GetArgumentsObjectEscapes() const { return HasFlags(kFunctionHasHeapArguments); }
- bool GetAsmjsMode() const { return HasFlags(kFunctionAsmjsMode); }
- bool GetStrictMode() const { return HasFlags(kFunctionStrictMode); }
- bool HasDefaultArguments() const { return HasFlags(kFunctionHasDefaultArguments); }
- bool HasDestructuredParams() const { return HasFlags(kFunctionHasDestructuredParams); }
- bool HasHeapArguments() const { return true; /* HasFlags(kFunctionHasHeapArguments); Disabling stack arguments. Always return HeapArguments as True */ }
- bool HasAnyWriteToFormals() const { return HasFlags((uint)kFunctionHasAnyWriteToFormals); }
- bool HasOnlyThisStmts() const { return !HasFlags(kFunctionHasNonThisStmt); }
- bool HasReferenceableBuiltInArguments() const { return HasFlags(kFunctionHasReferenceableBuiltInArguments); }
- bool HasSuperReference() const { return HasFlags(kFunctionHasSuperReference); }
- bool HasDirectSuper() const { return HasFlags(kFunctionHasDirectSuper); }
- bool HasNonSimpleParameterList() { return HasFlags(kFunctionHasNonSimpleParameterList); }
- bool HasWithStmt() const { return HasFlags(kFunctionHasWithStmt); }
- bool IsAccessor() const { return HasFlags(kFunctionIsAccessor); }
- bool IsAsync() const { return HasFlags(kFunctionIsAsync); }
- bool IsConstructor() const { return HasNoFlags(kFunctionIsAsync|kFunctionIsLambda|kFunctionIsAccessor); }
- bool IsClassConstructor() const { return HasFlags(kFunctionIsClassConstructor); }
- bool IsBaseClassConstructor() const { return HasFlags(kFunctionIsBaseClassConstructor); }
- bool IsDerivedClassConstructor() const { return IsClassConstructor() && !IsBaseClassConstructor(); }
- bool IsClassMember() const { return HasFlags(kFunctionIsClassMember); }
- bool IsDeclaration() const { return HasFlags(kFunctionDeclaration); }
- bool IsGeneratedDefault() const { return HasFlags(kFunctionIsGeneratedDefault); }
- bool IsGenerator() const { return HasFlags(kFunctionIsGenerator); }
- bool IsCoroutine() const { return HasAnyFlags(kFunctionIsGenerator | kFunctionIsAsync); }
- bool IsLambda() const { return HasFlags(kFunctionIsLambda); }
- bool IsMethod() const { return HasFlags(kFunctionIsMethod); }
- bool IsNested() const { return HasFlags(kFunctionNested); }
- bool IsStaticMember() const { return HasFlags(kFunctionIsStaticMember); }
- bool IsModule() const { return HasFlags(kFunctionIsModule); }
- bool HasComputedName() const { return HasFlags(kFunctionHasComputedName); }
- bool HasHomeObj() const { return HasFlags(kFunctionHasHomeObj); }
- bool UsesArguments() const { return HasFlags(kFunctionUsesArguments); }
- bool IsDefaultModuleExport() const { return HasFlags(kFunctionIsDefaultModuleExport); }
- bool IsDeclaredInParamScope() const { return HasFlags(kFunctionIsDeclaredInParamScope); }
- bool NestedFuncEscapes() const { return nestedFuncEscapes; }
- bool CanBeDeferred() const { return canBeDeferred; }
- bool IsBodyAndParamScopeMerged() { return isBodyAndParamScopeMerged; }
- Js::RegSlot GetHomeObjLocation() const { return homeObjLocation; }
- // Only allow the normal functions to be asm.js
- bool IsAsmJsAllowed() const { return (fncFlags & ~(
- kFunctionAsmjsMode |
- kFunctionNested |
- kFunctionDeclaration |
- kFunctionStrictMode |
- kFunctionHasReferenceableBuiltInArguments |
- kFunctionHasNonThisStmt |
- // todo:: we shouldn't accept kFunctionHasAnyWriteToFormals on the asm module, but it looks like a bug is setting that flag incorrectly
- kFunctionHasAnyWriteToFormals
- )) == 0; }
- size_t LengthInBytes()
- {
- return cbLim - cbMin;
- }
- Symbol *GetFuncSymbol();
- void SetFuncSymbol(Symbol *sym);
- ParseNodePtr GetParamScope() const;
- ParseNodePtr GetBodyScope() const;
- ParseNodePtr GetTopLevelScope() const
- {
- // Top level scope will be the same for knopProg and knopFncDecl.
- return GetParamScope();
- }
- template<typename Fn>
- void MapContainerScopes(Fn fn)
- {
- fn(this->pnodeScopes->pnodeScopes);
- if (this->pnodeBodyScope != nullptr)
- {
- fn(this->pnodeBodyScope->pnodeScopes);
- }
- }
- IdentPtrSet* EnsureCapturedNames(ArenaAllocator* alloc);
- IdentPtrSet* GetCapturedNames();
- bool HasAnyCapturedNames();
- DISABLE_SELF_CAST(ParseNodeFnc);
- };
- // class declaration
- class ParseNodeClass : public ParseNode
- {
- public:
- ParseNodeClass(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodeVar * pnodeName;
- ParseNodeVar * pnodeDeclName;
- ParseNodeBlock * pnodeBlock;
- ParseNodeFnc * pnodeConstructor;
- ParseNodePtr pnodeMembers;
- ParseNodePtr pnodeExtends;
- bool isDefaultModuleExport;
- void SetIsDefaultModuleExport(bool set) { isDefaultModuleExport = set; }
- bool IsDefaultModuleExport() const { return isDefaultModuleExport; }
- DISABLE_SELF_CAST(ParseNodeClass);
- };
- // export default expr
- class ParseNodeExportDefault : public ParseNode
- {
- public:
- ParseNodeExportDefault(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodePtr pnodeExpr;
- DISABLE_SELF_CAST(ParseNodeExportDefault);
- };
- // string template declaration
- class ParseNodeStrTemplate : public ParseNode
- {
- public:
- ParseNodeStrTemplate(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodePtr pnodeStringLiterals;
- ParseNodePtr pnodeStringRawLiterals;
- ParseNodePtr pnodeSubstitutionExpressions;
- uint16 countStringLiterals;
- BYTE isTaggedTemplate:1;
- DISABLE_SELF_CAST(ParseNodeStrTemplate);
- };
- // global program
- class ParseNodeProg : public ParseNodeFnc
- {
- public:
- ParseNodeProg(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodePtr pnodeLastValStmt; // Used by ByteCodeGenerator
- bool m_UsesArgumentsAtGlobal;
- DISABLE_SELF_CAST(ParseNodeProg);
- };
- // global module
- class ParseNodeModule : public ParseNodeProg
- {
- public:
- ParseNodeModule(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ModuleImportOrExportEntryList* localExportEntries;
- ModuleImportOrExportEntryList* indirectExportEntries;
- ModuleImportOrExportEntryList* starExportEntries;
- ModuleImportOrExportEntryList* importEntries;
- IdentPtrList* requestedModules;
- DISABLE_SELF_CAST(ParseNodeModule);
- };
- // function call
- class ParseNodeCall : public ParseNode
- {
- public:
- ParseNodeCall(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNodePtr pnodeTarget, ParseNodePtr pnodeArgs);
- ParseNodePtr pnodeTarget;
- ParseNodePtr pnodeArgs;
- uint16 argCount;
- uint16 spreadArgCount;
- BYTE callOfConstants : 1;
- BYTE isApplyCall : 1;
- BYTE isEvalCall : 1;
- BYTE isSuperCall : 1;
- BYTE hasDestructuring : 1;
- DISABLE_SELF_CAST(ParseNodeCall);
- };
- // base for statement nodes
- class ParseNodeStmt : public ParseNode
- {
- public:
- ParseNodeStmt(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- // Set by parsing code, used by code gen.
- uint grfnop;
- // Needed for byte code gen.
- Js::ByteCodeLabel breakLabel;
- Js::ByteCodeLabel continueLabel;
- bool emitLabels;
- DISABLE_SELF_CAST(ParseNodeStmt);
- };
- // block { }
- class ParseNodeBlock : public ParseNodeStmt
- {
- public:
- ParseNodeBlock(charcount_t ichMin, charcount_t ichLim, int blockId, PnodeBlockType blockType);
- ParseNodePtr pnodeStmt;
- ParseNodePtr pnodeLastValStmt;
- ParseNodePtr pnodeLexVars;
- ParseNodePtr pnodeScopes;
- ParseNodePtr pnodeNext;
- Scope *scope;
- ParseNodeBlock * enclosingBlock;
- int blockId;
- PnodeBlockType blockType:2;
- BYTE callsEval:1;
- BYTE childCallsEval:1;
- void SetCallsEval(bool does) { callsEval = does; }
- bool GetCallsEval() const { return callsEval; }
- void SetChildCallsEval(bool does) { childCallsEval = does; }
- bool GetChildCallsEval() const { return childCallsEval; }
- void SetEnclosingBlock(ParseNodeBlock * pnode) { enclosingBlock = pnode; }
- ParseNodeBlock * GetEnclosingBlock() const { return enclosingBlock; }
- bool HasBlockScopedContent() const;
- DISABLE_SELF_CAST(ParseNodeBlock);
- };
- // break and continue
- class ParseNodeJump : public ParseNodeStmt
- {
- public:
- ParseNodeJump(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodeStmt * pnodeTarget;
- bool hasExplicitTarget;
- DISABLE_SELF_CAST(ParseNodeJump);
- };
- // while and do-while loops
- class ParseNodeWhile : public ParseNodeStmt
- {
- public:
- ParseNodeWhile(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodePtr pnodeCond;
- ParseNodePtr pnodeBody;
- DISABLE_SELF_CAST(ParseNodeWhile);
- };
- // with
- class ParseNodeWith : public ParseNodeStmt
- {
- public:
- ParseNodeWith(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodePtr pnodeObj;
- ParseNodePtr pnodeBody;
- ParseNodePtr pnodeScopes;
- ParseNodePtr pnodeNext;
- Scope *scope;
- DISABLE_SELF_CAST(ParseNodeWith);
- };
- // Destructure pattern for function/catch parameter
- class ParseNodeParamPattern : public ParseNodeUni
- {
- public:
- ParseNodeParamPattern(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodePtr pnodeNext;
- Js::RegSlot location;
- DISABLE_SELF_CAST(ParseNodeParamPattern);
- };
- // if
- class ParseNodeIf : public ParseNodeStmt
- {
- public:
- ParseNodeIf(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodePtr pnodeCond;
- ParseNodePtr pnodeTrue;
- ParseNodePtr pnodeFalse;
- DISABLE_SELF_CAST(ParseNodeIf);
- };
- // for-in loop
- class ParseNodeForInOrForOf : public ParseNodeStmt
- {
- public:
- ParseNodeForInOrForOf(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodePtr pnodeObj;
- ParseNodePtr pnodeBody;
- ParseNodePtr pnodeLval;
- ParseNodeBlock * pnodeBlock;
- Js::RegSlot itemLocation;
- Js::RegSlot shouldCallReturnFunctionLocation;
- Js::RegSlot shouldCallReturnFunctionLocationFinally;
- DISABLE_SELF_CAST(ParseNodeForInOrForOf);
- };
- // for loop
- class ParseNodeFor : public ParseNodeStmt
- {
- public:
- ParseNodeFor(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodePtr pnodeCond;
- ParseNodePtr pnodeBody;
- ParseNodePtr pnodeInit;
- ParseNodePtr pnodeIncr;
- ParseNodeBlock * pnodeBlock;
- ParseNodeFor * pnodeInverted;
- DISABLE_SELF_CAST(ParseNodeFor);
- };
- // switch
- class ParseNodeSwitch : public ParseNodeStmt
- {
- public:
- ParseNodeSwitch(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodePtr pnodeVal;
- ParseNodeCase * pnodeCases;
- ParseNodeCase * pnodeDefault;
- ParseNodeBlock * pnodeBlock;
- DISABLE_SELF_CAST(ParseNodeSwitch);
- };
- // switch case
- class ParseNodeCase : public ParseNodeStmt
- {
- public:
- ParseNodeCase(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodeCase * pnodeNext;
- ParseNodePtr pnodeExpr; // nullptr for default
- ParseNodeBlock * pnodeBody;
- Js::ByteCodeLabel labelCase;
- DISABLE_SELF_CAST(ParseNodeCase);
- };
- // return [expr]
- class ParseNodeReturn : public ParseNodeStmt
- {
- public:
- ParseNodeReturn(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodePtr pnodeExpr;
- DISABLE_SELF_CAST(ParseNodeReturn);
- };
- // try-catch-finally
- class ParseNodeTryFinally : public ParseNodeStmt
- {
- public:
- ParseNodeTryFinally(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodeTry * pnodeTry;
- ParseNodeFinally * pnodeFinally;
- DISABLE_SELF_CAST(ParseNodeTryFinally);
- };
- // try-catch
- class ParseNodeTryCatch : public ParseNodeStmt
- {
- public:
- ParseNodeTryCatch(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodeTry * pnodeTry;
- ParseNodeCatch * pnodeCatch;
- DISABLE_SELF_CAST(ParseNodeTryCatch);
- };
- // try-catch
- class ParseNodeTry : public ParseNodeStmt
- {
- public:
- ParseNodeTry(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodePtr pnodeBody;
- DISABLE_SELF_CAST(ParseNodeTry);
- };
- // { catch(e : expr) {body} }
- class ParseNodeCatch : public ParseNodeStmt
- {
- public:
- ParseNodeCatch(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- bool HasPatternParam() { return pnodeParam != nullptr && pnodeParam->nop == knopParamPattern; }
- bool HasParam() { return pnodeParam != nullptr; }
- ParseNodePtr GetParam() { return pnodeParam; }
- void SetParam(ParseNodeName * pnode) { pnodeParam = pnode; }
- void SetParam(ParseNodeParamPattern * pnode) { pnodeParam = pnode; }
- ParseNodePtr pnodeNext;
- private:
- ParseNode * pnodeParam; // Name or ParamPattern
- public:
- ParseNodePtr pnodeBody;
- ParseNodePtr pnodeScopes;
- Scope *scope;
- DISABLE_SELF_CAST(ParseNodeCatch);
- };
- // finally
- class ParseNodeFinally : public ParseNodeStmt
- {
- public:
- ParseNodeFinally(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodePtr pnodeBody;
- DISABLE_SELF_CAST(ParseNodeFinally);
- };
- // special name like 'this'
- class ParseNodeSpecialName : public ParseNodeName
- {
- public:
- ParseNodeSpecialName(charcount_t ichMin, charcount_t ichLim, IdentPtr pid);
- bool isThis : 1;
- bool isSuper : 1;
- DISABLE_SELF_CAST(ParseNodeSpecialName);
- };
- // binary operator with super reference
- class ParseNodeSuperReference : public ParseNodeBin
- {
- public:
- ParseNodeSuperReference(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnode1, ParseNode * pnode2);
- ParseNodeSpecialName * pnodeThis;
- DISABLE_SELF_CAST(ParseNodeSuperReference);
- };
- // call node with super target
- class ParseNodeSuperCall : public ParseNodeCall
- {
- public:
- ParseNodeSuperCall(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnodeTarget, ParseNode * pnodeArgs);
- ParseNodeSpecialName * pnodeThis;
- ParseNodeSpecialName * pnodeNewTarget;
- DISABLE_SELF_CAST(ParseNodeSuperCall);
- };
- typedef ParseNode ParseNodeNone;
- template <OpCode nop> class OpCodeTrait;
- #define PTNODE(nop,sn,pc,nk,ok,json) \
- template<> \
- class OpCodeTrait<nop> \
- { \
- public: \
- typedef ParseNode##nk ParseNodeType; \
- static const bool AllowDefer = ((ok) & fnopAllowDefer) != 0; \
- };
- #include "ptlist.h"
|