| //------------------------------------------------------------------------------------------------------- |
| // Copyright (C) Microsoft. All rights reserved. |
| // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. |
| //------------------------------------------------------------------------------------------------------- |
| #include "ParserPch.h" |
| |
| ParseNode::ParseNode(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| { |
| this->nop = nop; |
| this->grfpn = PNodeFlags::fpnNone; |
| this->location = Js::Constants::NoRegister; |
| this->isUsed = true; |
| this->notEscapedUse = false; |
| this->isInList = false; |
| this->isPatternDeclaration = false; |
| this->isCallApplyTargetLoad = false; |
| this->ichMin = ichMin; |
| this->ichLim = ichLim; |
| } |
| |
| ParseNodeUni * ParseNode::AsParseNodeUni() |
| { |
| Assert((this->Grfnop() & fnopUni) || this->nop == knopThrow); |
| return reinterpret_cast<ParseNodeUni *>(this); |
| } |
| |
| ParseNodeBin * ParseNode::AsParseNodeBin() |
| { |
| Assert((this->Grfnop() & fnopBin) || this->nop == knopList); |
| return reinterpret_cast<ParseNodeBin *>(this); |
| } |
| |
| ParseNodeTri * ParseNode::AsParseNodeTri() |
| { |
| Assert(this->nop == knopQmark); |
| return reinterpret_cast<ParseNodeTri *>(this); |
| } |
| |
| ParseNodeInt * ParseNode::AsParseNodeInt() |
| { |
| Assert(this->nop == knopInt); |
| return reinterpret_cast<ParseNodeInt *>(this); |
| } |
| |
| ParseNodeBigInt * ParseNode::AsParseNodeBigInt() |
| { |
| Assert(this->nop == knopBigInt); |
| return reinterpret_cast<ParseNodeBigInt *>(this); |
| } |
| |
| ParseNodeFloat * ParseNode::AsParseNodeFloat() |
| { |
| Assert(this->nop == knopFlt); |
| return reinterpret_cast<ParseNodeFloat *>(this); |
| } |
| |
| ParseNodeRegExp * ParseNode::AsParseNodeRegExp() |
| { |
| Assert(this->nop == knopRegExp); |
| return reinterpret_cast<ParseNodeRegExp *>(this); |
| } |
| |
| ParseNodeVar * ParseNode::AsParseNodeVar() |
| { |
| Assert(this->nop == knopVarDecl || this->nop == knopConstDecl || this->nop == knopLetDecl || this->nop == knopTemp); |
| return reinterpret_cast<ParseNodeVar *>(this); |
| } |
| |
| ParseNodeStr * ParseNode::AsParseNodeStr() |
| { |
| Assert(this->nop == knopStr); |
| return reinterpret_cast<ParseNodeStr *>(this); |
| } |
| |
| ParseNodeName * ParseNode::AsParseNodeName() |
| { |
| Assert(this->nop == knopName); |
| return reinterpret_cast<ParseNodeName *>(this); |
| } |
| |
| ParseNodeSpecialName * ParseNode::AsParseNodeSpecialName() |
| { |
| Assert(this->nop == knopName && this->AsParseNodeName()->IsSpecialName()); |
| return reinterpret_cast<ParseNodeSpecialName *>(this); |
| } |
| |
| ParseNodeExportDefault * ParseNode::AsParseNodeExportDefault() |
| { |
| Assert(this->nop == knopExportDefault); |
| return reinterpret_cast<ParseNodeExportDefault *>(this); |
| } |
| |
| ParseNodeStrTemplate * ParseNode::AsParseNodeStrTemplate() |
| { |
| Assert(this->nop == knopStrTemplate); |
| return reinterpret_cast<ParseNodeStrTemplate *>(this); |
| } |
| |
| ParseNodeSuperReference * ParseNode::AsParseNodeSuperReference() |
| { |
| Assert(this->nop == knopDot || this->nop == knopIndex); |
| Assert(this->AsParseNodeBin()->pnode1 && this->AsParseNodeBin()->pnode1->AsParseNodeSpecialName()->isSuper); |
| return reinterpret_cast<ParseNodeSuperReference*>(this); |
| } |
| |
| ParseNodeArrLit * ParseNode::AsParseNodeArrLit() |
| { |
| Assert(this->nop == knopArray || this->nop == knopArrayPattern); |
| return reinterpret_cast<ParseNodeArrLit*>(this); |
| } |
| |
| ParseNodeObjLit * ParseNode::AsParseNodeObjLit() |
| { |
| // Currently only Object Assignment Pattern needs extra field to count members |
| Assert(this->nop == knopObjectPattern); |
| return reinterpret_cast<ParseNodeObjLit*>(this); |
| } |
| |
| ParseNodeCall * ParseNode::AsParseNodeCall() |
| { |
| Assert(this->nop == knopCall || this->nop == knopNew); |
| return reinterpret_cast<ParseNodeCall*>(this); |
| } |
| |
| ParseNodeSuperCall * ParseNode::AsParseNodeSuperCall() |
| { |
| Assert(this->nop == knopCall && this->AsParseNodeCall()->isSuperCall); |
| return reinterpret_cast<ParseNodeSuperCall*>(this); |
| } |
| |
| ParseNodeClass * ParseNode::AsParseNodeClass() |
| { |
| Assert(this->nop == knopClassDecl); |
| return reinterpret_cast<ParseNodeClass*>(this); |
| } |
| |
| ParseNodeParamPattern * ParseNode::AsParseNodeParamPattern() |
| { |
| Assert(this->nop == knopParamPattern); |
| return reinterpret_cast<ParseNodeParamPattern*>(this); |
| } |
| |
| ParseNodeStmt * ParseNode::AsParseNodeStmt() |
| { |
| Assert(this->nop == knopBlock || this->nop == knopBreak || this->nop == knopContinue || this->nop == knopWith || this->nop == knopIf || this->nop == knopSwitch || this->nop == knopCase || this->nop == knopReturn |
| || this->nop == knopTryFinally || this->nop == knopTryCatch || this->nop == knopTry || this->nop == knopCatch || this->nop == knopFinally |
| || this->nop == knopWhile || this->nop == knopDoWhile || this->nop == knopFor || this->nop == knopForIn || this->nop == knopForOf); |
| return reinterpret_cast<ParseNodeStmt*>(this); |
| } |
| |
| ParseNodeBlock * ParseNode::AsParseNodeBlock() |
| { |
| Assert(this->nop == knopBlock); |
| return reinterpret_cast<ParseNodeBlock*>(this); |
| } |
| |
| ParseNodeJump * ParseNode::AsParseNodeJump() |
| { |
| Assert(this->nop == knopBreak || this->nop == knopContinue); |
| return reinterpret_cast<ParseNodeJump*>(this); |
| } |
| |
| ParseNodeWith * ParseNode::AsParseNodeWith() |
| { |
| Assert(this->nop == knopWith); |
| return reinterpret_cast<ParseNodeWith*>(this); |
| } |
| |
| ParseNodeIf * ParseNode::AsParseNodeIf() |
| { |
| Assert(this->nop == knopIf); |
| return reinterpret_cast<ParseNodeIf*>(this); |
| } |
| |
| ParseNodeSwitch * ParseNode::AsParseNodeSwitch() |
| { |
| Assert(this->nop == knopSwitch); |
| return reinterpret_cast<ParseNodeSwitch*>(this); |
| } |
| |
| ParseNodeCase * ParseNode::AsParseNodeCase() |
| { |
| Assert(this->nop == knopCase); |
| return reinterpret_cast<ParseNodeCase*>(this); |
| } |
| |
| ParseNodeReturn * ParseNode::AsParseNodeReturn() |
| { |
| Assert(this->nop == knopReturn); |
| return reinterpret_cast<ParseNodeReturn*>(this); |
| } |
| |
| ParseNodeTryFinally * ParseNode::AsParseNodeTryFinally() |
| { |
| Assert(this->nop == knopTryFinally); |
| return reinterpret_cast<ParseNodeTryFinally*>(this); |
| } |
| |
| ParseNodeTryCatch * ParseNode::AsParseNodeTryCatch() |
| { |
| Assert(this->nop == knopTryCatch); |
| return reinterpret_cast<ParseNodeTryCatch*>(this); |
| } |
| |
| ParseNodeTry * ParseNode::AsParseNodeTry() |
| { |
| Assert(this->nop == knopTry); |
| return reinterpret_cast<ParseNodeTry*>(this); |
| } |
| |
| ParseNodeCatch * ParseNode::AsParseNodeCatch() |
| { |
| Assert(this->nop == knopCatch); |
| return reinterpret_cast<ParseNodeCatch*>(this); |
| } |
| |
| ParseNodeFinally * ParseNode::AsParseNodeFinally() |
| { |
| Assert(this->nop == knopFinally); |
| return reinterpret_cast<ParseNodeFinally*>(this); |
| } |
| |
| ParseNodeLoop * ParseNode::AsParseNodeLoop() |
| { |
| Assert(this->nop == knopWhile || this->nop == knopDoWhile || this->nop == knopFor || this->nop == knopForIn || this->nop == knopForOf); |
| return reinterpret_cast<ParseNodeLoop*>(this); |
| } |
| |
| ParseNodeWhile * ParseNode::AsParseNodeWhile() |
| { |
| Assert(this->nop == knopWhile || this->nop == knopDoWhile); |
| return reinterpret_cast<ParseNodeWhile*>(this); |
| } |
| |
| ParseNodeFor * ParseNode::AsParseNodeFor() |
| { |
| Assert(this->nop == knopFor); |
| return reinterpret_cast<ParseNodeFor*>(this); |
| } |
| |
| ParseNodeForInOrForOf * ParseNode::AsParseNodeForInOrForOf() |
| { |
| Assert(this->nop == knopForIn || this->nop == knopForOf); |
| return reinterpret_cast<ParseNodeForInOrForOf*>(this); |
| } |
| |
| ParseNodeFnc * ParseNode::AsParseNodeFnc() |
| { |
| Assert(this->nop == knopFncDecl || this->nop == knopProg || this->nop == knopModule); |
| return reinterpret_cast<ParseNodeFnc*>(this); |
| } |
| |
| ParseNodeProg * ParseNode::AsParseNodeProg() |
| { |
| Assert(this->nop == knopProg); |
| return reinterpret_cast<ParseNodeProg*>(this); |
| } |
| |
| ParseNodeModule * ParseNode::AsParseNodeModule() |
| { |
| // TODO: Currently there is not way to distingish a ParseNodeModule to ParseNodeProg node |
| Assert(this->nop == knopProg); |
| return reinterpret_cast<ParseNodeModule*>(this); |
| } |
| |
| IdentPtr ParseNode::name() |
| { |
| if (this->nop == knopStr) |
| { |
| return this->AsParseNodeStr()->pid; |
| } |
| else if (this->nop == knopName) |
| { |
| return this->AsParseNodeName()->pid; |
| } |
| else if (this->nop == knopVarDecl || this->nop == knopConstDecl) |
| { |
| return this->AsParseNodeVar()->pid; |
| } |
| return nullptr; |
| } |
| |
| ParseNodePtr ParseNode::GetFormalNext() |
| { |
| ParseNodePtr pnodeNext = nullptr; |
| |
| if (nop == knopParamPattern) |
| { |
| pnodeNext = this->AsParseNodeParamPattern()->pnodeNext; |
| } |
| else |
| { |
| Assert(IsVarLetOrConst()); |
| pnodeNext = this->AsParseNodeVar()->pnodeNext; |
| } |
| return pnodeNext; |
| } |
| |
| bool ParseNode::IsUserIdentifier() |
| { |
| return this->nop == knopName && !this->AsParseNodeName()->IsSpecialName(); |
| } |
| |
| ParseNodeUni::ParseNodeUni(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnode1) |
| : ParseNode(nop, ichMin, ichLim) |
| { |
| this->pnode1 = pnode1; |
| } |
| |
| ParseNodeBin::ParseNodeBin(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnode1, ParseNode * pnode2) |
| : ParseNode(nop, ichMin, ichLim) |
| { |
| // Member name is either a string or a computed name |
| Assert((nop != knopMember && nop != knopMemberShort && nop != knopObjectPatternMember && nop != knopGetMember && nop != knopSetMember) |
| || (pnode1->nop == knopStr || pnode1->nop == knopComputedName)); |
| |
| // Dot's rhs has to be a name; |
| Assert(nop != knopDot || pnode2->nop == knopName); |
| |
| this->pnode1 = pnode1; |
| this->pnode2 = pnode2; |
| |
| // Statically detect if the add is a concat |
| if (!PHASE_OFF1(Js::ByteCodeConcatExprOptPhase)) |
| { |
| // We can't flatten the concat expression if the LHS is not a flatten concat already |
| // e.g. a + (<str> + b) |
| // Side effect of ToStr(b) need to happen first before ToStr(a) |
| // If we flatten the concat expression, we will do ToStr(a) before ToStr(b) |
| if ((nop == knopAdd) && (pnode1->CanFlattenConcatExpr() || pnode2->nop == knopStr)) |
| { |
| this->grfpn |= fpnCanFlattenConcatExpr; |
| } |
| } |
| } |
| |
| ParseNodeTri::ParseNodeTri(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNode(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeInt::ParseNodeInt(charcount_t ichMin, charcount_t ichLim, int32 lw) |
| : ParseNode(knopInt, ichMin, ichLim) |
| { |
| this->lw = lw; |
| } |
| |
| ParseNodeFloat::ParseNodeFloat(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNode(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeRegExp::ParseNodeRegExp(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNode(nop, ichMin, ichLim) |
| { |
| this->regexPattern = nullptr; |
| this->regexPatternIndex = 0; |
| } |
| |
| ParseNodeStr::ParseNodeStr(charcount_t ichMin, charcount_t ichLim, IdentPtr name) |
| : ParseNode(knopStr, ichMin, ichLim), pid(name) |
| { |
| } |
| |
| ParseNodeBigInt::ParseNodeBigInt(charcount_t ichMin, charcount_t ichLim, IdentPtr name) |
| : ParseNode(knopBigInt, ichMin, ichLim), pid(name) |
| { |
| } |
| |
| |
| ParseNodeName::ParseNodeName(charcount_t ichMin, charcount_t ichLim, IdentPtr name) |
| : ParseNode(knopName, ichMin, ichLim), pid(name) |
| { |
| this->sym = nullptr; |
| this->symRef = nullptr; |
| this->isSpecialName = false; |
| } |
| |
| void ParseNodeName::SetSymRef(PidRefStack * ref) |
| { |
| Assert(this->symRef == nullptr); |
| this->symRef = ref->GetSymRef(); |
| } |
| |
| Js::PropertyId ParseNodeName::PropertyIdFromNameNode() const |
| { |
| Js::PropertyId propertyId; |
| Symbol *sym = this->sym; |
| if (sym) |
| { |
| propertyId = sym->GetPosition(); |
| } |
| else |
| { |
| propertyId = this->pid->GetPropertyId(); |
| } |
| return propertyId; |
| } |
| |
| ParseNodeVar::ParseNodeVar(OpCode nop, charcount_t ichMin, charcount_t ichLim, IdentPtr name) |
| : ParseNode(nop, ichMin, ichLim), pid(name) |
| { |
| Assert(nop == knopVarDecl || nop == knopConstDecl || nop == knopLetDecl || nop == knopTemp); |
| |
| this->pnodeInit = nullptr; |
| this->pnodeNext = nullptr; |
| this->sym = nullptr; |
| this->symRef = nullptr; |
| this->isSwitchStmtDecl = false; |
| this->isBlockScopeFncDeclVar = false; |
| } |
| |
| ParseNodeArrLit::ParseNodeArrLit(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeUni(nop, ichMin, ichLim, nullptr) |
| { |
| } |
| |
| ParseNodeObjLit::ParseNodeObjLit(OpCode nop, charcount_t ichMin, charcount_t ichLim, uint staticCnt, uint computedCnt, bool rest) |
| : ParseNodeUni(nop, ichMin, ichLim, nullptr), staticCount(staticCnt), computedCount(computedCnt), hasRest(rest) |
| { |
| } |
| |
| ParseNodeFnc::ParseNodeFnc(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNode(nop, ichMin, ichLim) |
| { |
| this->ClearFlags(); // Initialize fncFlags, canBeDeferred and isBodyAndParamScopeMerged |
| this->SetDeclaration(false); |
| this->pnodeNext = nullptr; |
| this->pnodeName = nullptr; |
| this->pid = nullptr; |
| this->hint = nullptr; |
| this->hintOffset = 0; |
| this->hintLength = 0; |
| this->isNameIdentifierRef = true; |
| this->nestedFuncEscapes = false; |
| this->pnodeScopes = nullptr; |
| this->pnodeBodyScope = nullptr; |
| this->pnodeParams = nullptr; |
| this->pnodeVars = nullptr; |
| this->pnodeBody = nullptr; |
| this->pnodeRest = nullptr; |
| |
| this->funcInfo = nullptr; |
| this->scope = nullptr; |
| this->nestedCount = 0; |
| this->nestedIndex = (uint)-1; |
| this->firstDefaultArg = 0; |
| |
| this->astSize = 0; |
| this->cbMin = 0; |
| this->cbStringMin = 0; |
| this->cbLim = 0; |
| this->lineNumber = 0; |
| this->columnNumber = 0; |
| this->functionId = 0; |
| #if DBG |
| this->deferredParseNextFunctionId = Js::Constants::NoFunctionId; |
| #endif |
| this->pRestorePoint = nullptr; |
| this->deferredStub = nullptr; |
| this->capturedNames = nullptr; |
| this->superRestrictionState = SuperRestrictionState::Disallowed; |
| } |
| |
| ParseNodeClass::ParseNodeClass(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNode(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeExportDefault::ParseNodeExportDefault(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNode(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeStrTemplate::ParseNodeStrTemplate(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNode(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeProg::ParseNodeProg(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeFnc(nop, ichMin, ichLim) |
| { |
| this->pnodeLastValStmt = nullptr; |
| this->m_UsesArgumentsAtGlobal = false; |
| } |
| |
| ParseNodeModule::ParseNodeModule(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeProg(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeCall::ParseNodeCall(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNodePtr pnodeTarget, ParseNodePtr pnodeArgs) |
| : ParseNode(nop, ichMin, ichLim) |
| { |
| this->pnodeTarget = pnodeTarget; |
| this->pnodeArgs = pnodeArgs; |
| this->argCount = 0; |
| this->spreadArgCount = 0; |
| this->callOfConstants = false; |
| this->isApplyCall = false; |
| this->isEvalCall = false; |
| this->isSuperCall = false; |
| this->hasDestructuring = false; |
| } |
| |
| ParseNodeStmt::ParseNodeStmt(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNode(nop, ichMin, ichLim) |
| { |
| this->emitLabels = false; |
| } |
| |
| ParseNodeBlock::ParseNodeBlock(charcount_t ichMin, charcount_t ichLim, int blockId, PnodeBlockType blockType) |
| : ParseNodeStmt(knopBlock, ichMin, ichLim) |
| { |
| this->pnodeScopes = nullptr; |
| this->pnodeNext = nullptr; |
| this->scope = nullptr; |
| this->enclosingBlock = nullptr; |
| this->pnodeLexVars = nullptr; |
| this->pnodeStmt = nullptr; |
| this->pnodeLastValStmt = nullptr; |
| |
| this->callsEval = false; |
| this->childCallsEval = false; |
| this->blockType = blockType; |
| this->blockId = blockId; |
| |
| if (blockType != PnodeBlockType::Regular) |
| { |
| this->grfpn |= PNodeFlags::fpnSyntheticNode; |
| } |
| } |
| |
| ParseNodeJump::ParseNodeJump(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeStmt(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeLoop::ParseNodeLoop(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeStmt(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeWhile::ParseNodeWhile(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeLoop(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeWith::ParseNodeWith(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeStmt(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeParamPattern::ParseNodeParamPattern(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeUni(nop, ichMin, ichLim, nullptr) |
| { |
| } |
| |
| ParseNodeIf::ParseNodeIf(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeStmt(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeForInOrForOf::ParseNodeForInOrForOf(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeLoop(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeFor::ParseNodeFor(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeLoop(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeSwitch::ParseNodeSwitch(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeStmt(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeCase::ParseNodeCase(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeStmt(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeReturn::ParseNodeReturn(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeStmt(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeTryFinally::ParseNodeTryFinally(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeStmt(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeTryCatch::ParseNodeTryCatch(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeStmt(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeTry::ParseNodeTry(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeStmt(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeCatch::ParseNodeCatch(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeStmt(nop, ichMin, ichLim), pnodeParam(nullptr) |
| { |
| } |
| |
| ParseNodeFinally::ParseNodeFinally(OpCode nop, charcount_t ichMin, charcount_t ichLim) |
| : ParseNodeStmt(nop, ichMin, ichLim) |
| { |
| } |
| |
| ParseNodeSpecialName::ParseNodeSpecialName(charcount_t ichMin, charcount_t ichLim, IdentPtr pid) |
| : ParseNodeName(ichMin, ichLim, pid) |
| { |
| this->SetIsSpecialName(); |
| this->isThis = false; |
| this->isSuper = false; |
| } |
| |
| ParseNodeSuperReference::ParseNodeSuperReference(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnode1, ParseNode * pnode2) |
| : ParseNodeBin(nop, ichMin, ichLim, pnode1, pnode2) |
| { |
| this->pnodeThis = nullptr; |
| } |
| |
| ParseNodeSuperCall::ParseNodeSuperCall(OpCode nop, charcount_t ichMin, charcount_t ichLim, ParseNode * pnodeTarget, ParseNode * pnodeArgs) |
| : ParseNodeCall(nop, ichMin, ichLim, pnodeTarget, pnodeArgs) |
| { |
| this->isSuperCall = true; |
| this->pnodeThis = nullptr; |
| this->pnodeNewTarget = nullptr; |
| } |
| |
| IdentPtrSet* ParseNodeFnc::EnsureCapturedNames(ArenaAllocator* alloc) |
| { |
| if (this->capturedNames == nullptr) |
| { |
| this->capturedNames = Anew(alloc, IdentPtrSet, alloc); |
| } |
| return this->capturedNames; |
| } |
| |
| IdentPtrSet* ParseNodeFnc::GetCapturedNames() |
| { |
| return this->capturedNames; |
| } |
| |
| bool ParseNodeFnc::HasAnyCapturedNames() |
| { |
| return this->capturedNames != nullptr && this->capturedNames->Count() != 0; |
| } |