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