| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084 |
- //-------------------------------------------------------------------------------------------------------
- // 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 ParseNodeFloat;
- class ParseNodeRegExp;
- class ParseNodeStr;
- class ParseNodeName;
- class ParseNodeVar;
- class ParseNodeCall;
- class ParseNodeSuperCall;
- class ParseNodeSpecialName;
- class ParseNodeExportDefault;
- class ParseNodeStrTemplate;
- class ParseNodeSuperReference;
- class ParseNodeArrLit;
- 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 ParseNodeLoop;
- 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();
- ParseNodeFloat * AsParseNodeFloat();
- ParseNodeRegExp * AsParseNodeRegExp();
- ParseNodeVar * AsParseNodeVar();
- ParseNodeStr * AsParseNodeStr();
- ParseNodeName * AsParseNodeName();
- ParseNodeSpecialName * AsParseNodeSpecialName();
- ParseNodeExportDefault * AsParseNodeExportDefault();
- ParseNodeStrTemplate * AsParseNodeStrTemplate();
- ParseNodeSuperReference * AsParseNodeSuperReference();
- ParseNodeArrLit * AsParseNodeArrLit();
- 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();
- ParseNodeLoop * AsParseNodeLoop();
- 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);
- };
- // 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 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;
- bool isNameIdentifierRef;
- bool nestedFuncEscapes;
- ParseNodeBlock * pnodeScopes;
- ParseNodeBlock * pnodeBodyScope;
- ParseNodePtr pnodeParams;
- ParseNodePtr pnodeVars;
- ParseNodePtr pnodeBody;
- ParseNodeVar * 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)
- uint16 firstDefaultArg; // Position of the first default argument, if any
- FncFlags fncFlags;
- int32 astSize;
- size_t cbMin; // Min an Lim UTF8 offsets.
- 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;
- 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 pnodeStaticMembers;
- 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);
- ParseNodeStmt * pnodeOuter;
- // 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);
- };
- // base for loop nodes
- class ParseNodeLoop : public ParseNodeStmt
- {
- public:
- ParseNodeLoop(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- // Needed for byte code gen
- uint loopId;
- DISABLE_SELF_CAST(ParseNodeLoop);
- };
- // while and do-while loops
- class ParseNodeWhile : public ParseNodeLoop
- {
- 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 ParseNodeLoop
- {
- public:
- ParseNodeForInOrForOf(OpCode nop, charcount_t ichMin, charcount_t ichLim);
- ParseNodePtr pnodeObj;
- ParseNodePtr pnodeBody;
- ParseNodePtr pnodeLval;
- ParseNodeBlock * pnodeBlock;
- Js::RegSlot itemLocation;
- DISABLE_SELF_CAST(ParseNodeForInOrForOf);
- };
- // for loop
- class ParseNodeFor : public ParseNodeLoop
- {
- 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);
- 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"
|