Scope.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "RuntimeByteCodePch.h"
  6. bool Scope::IsGlobalEvalBlockScope() const
  7. {
  8. return this->scopeType == ScopeType_GlobalEvalBlock;
  9. }
  10. bool Scope::IsBlockScope(FuncInfo *funcInfo)
  11. {
  12. return this != funcInfo->GetBodyScope() && this != funcInfo->GetParamScope();
  13. }
  14. int Scope::AddScopeSlot()
  15. {
  16. int slot = scopeSlotCount++;
  17. if (scopeSlotCount == Js::ScopeSlots::MaxEncodedSlotCount)
  18. {
  19. this->GetEnclosingFunc()->SetHasMaybeEscapedNestedFunc(DebugOnly(_u("TooManySlots")));
  20. }
  21. return slot;
  22. }
  23. void Scope::ForceAllSymbolNonLocalReference(ByteCodeGenerator *byteCodeGenerator)
  24. {
  25. this->ForEachSymbol([this, byteCodeGenerator](Symbol *const sym)
  26. {
  27. if (!sym->GetIsArguments())
  28. {
  29. sym->SetHasNonLocalReference();
  30. byteCodeGenerator->ProcessCapturedSym(sym);
  31. this->GetFunc()->SetHasLocalInClosure(true);
  32. }
  33. });
  34. }
  35. bool Scope::IsEmpty() const
  36. {
  37. if (GetFunc()->bodyScope == this || (GetFunc()->IsGlobalFunction() && this->IsGlobalEvalBlockScope()))
  38. {
  39. return Count() == 0 && !GetFunc()->isThisLexicallyCaptured;
  40. }
  41. else
  42. {
  43. return Count() == 0;
  44. }
  45. }
  46. void Scope::SetIsObject()
  47. {
  48. if (this->isObject)
  49. {
  50. return;
  51. }
  52. this->isObject = true;
  53. // We might set the scope to be object after we have process the symbol
  54. // (e.g. "With" scope referencing a symbol in an outer scope).
  55. // If we have func assignment, we need to mark the function to not do stack nested function
  56. // as these are now assigned to a scope object.
  57. FuncInfo * funcInfo = this->GetFunc();
  58. if (funcInfo && !funcInfo->HasMaybeEscapedNestedFunc())
  59. {
  60. this->ForEachSymbolUntil([funcInfo](Symbol * const sym)
  61. {
  62. if (sym->GetHasFuncAssignment())
  63. {
  64. funcInfo->SetHasMaybeEscapedNestedFunc(DebugOnly(_u("DelayedObjectScopeAssignment")));
  65. return true;
  66. }
  67. return false;
  68. });
  69. }
  70. if (this->GetScopeType() == ScopeType_FunctionBody && funcInfo && !funcInfo->IsBodyAndParamScopeMerged()
  71. && funcInfo->paramScope && !funcInfo->paramScope->GetIsObject())
  72. {
  73. // If this is split scope then mark the param scope also as an object
  74. funcInfo->paramScope->SetIsObject();
  75. }
  76. }
  77. void Scope::MergeParamAndBodyScopes(ParseNode *pnodeScope)
  78. {
  79. Assert(pnodeScope->sxFnc.funcInfo);
  80. Scope *paramScope = pnodeScope->sxFnc.pnodeScopes->sxBlock.scope;
  81. Scope *bodyScope = pnodeScope->sxFnc.pnodeBodyScope->sxBlock.scope;
  82. if (paramScope->Count() == 0)
  83. {
  84. return;
  85. }
  86. bodyScope->scopeSlotCount = paramScope->scopeSlotCount;
  87. paramScope->ForEachSymbol([&](Symbol * sym)
  88. {
  89. bodyScope->AddNewSymbol(sym);
  90. });
  91. if (paramScope->GetIsObject())
  92. {
  93. bodyScope->SetIsObject();
  94. }
  95. if (paramScope->GetMustInstantiate())
  96. {
  97. bodyScope->SetMustInstantiate(true);
  98. }
  99. if (paramScope->GetHasOwnLocalInClosure())
  100. {
  101. bodyScope->SetHasOwnLocalInClosure(true);
  102. }
  103. }
  104. void Scope::RemoveParamScope(ParseNode *pnodeScope)
  105. {
  106. Assert(pnodeScope->sxFnc.funcInfo);
  107. Scope *paramScope = pnodeScope->sxFnc.pnodeScopes->sxBlock.scope;
  108. Scope *bodyScope = pnodeScope->sxFnc.pnodeBodyScope->sxBlock.scope;
  109. // Once the scopes are merged, there's no reason to instantiate the param scope.
  110. paramScope->SetMustInstantiate(false);
  111. paramScope->m_count = 0;
  112. paramScope->scopeSlotCount = 0;
  113. paramScope->m_symList = nullptr;
  114. // Remove the parameter scope from the scope chain.
  115. bodyScope->SetEnclosingScope(paramScope->GetEnclosingScope());
  116. }