• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "regScope.h"
17 
18 #include <compiler/base/hoisting.h>
19 #include <compiler/core/pandagen.h>
20 
21 namespace panda::es2panda::compiler {
22 
23 // RegScope
24 
RegScope(PandaGen * pg)25 RegScope::RegScope(PandaGen *pg) : pg_(pg), regBase_(pg_->usedRegs_) {}
26 
~RegScope()27 RegScope::~RegScope()
28 {
29     pg_->totalRegs_ = std::max(pg_->totalRegs_, pg_->usedRegs_);
30     pg_->usedRegs_ = regBase_;
31 }
32 
DebuggerCloseScope()33 void RegScope::DebuggerCloseScope()
34 {
35     if (!pg_->IsDebug()) {
36         return;
37     }
38 
39     if (insStartIndex_ < pg_->insns_.size()) {
40         auto it = pg_->insns_.begin();
41         std::advance(it, insStartIndex_);
42         pg_->scope_->SetScopeStart(*it);
43     } else {
44         pg_->scope_->SetScopeStart(pg_->insns_.back());
45     }
46 
47     pg_->scope_->SetScopeEnd(pg_->insns_.back());
48 }
49 
50 // LocalRegScope
51 
LocalRegScope(PandaGen * pg)52 LocalRegScope::LocalRegScope(PandaGen *pg) : RegScope(pg) {}
53 
LocalRegScope(PandaGen * pg,binder::Scope * scope)54 LocalRegScope::LocalRegScope(PandaGen *pg, binder::Scope *scope) : RegScope(pg)
55 {
56     prevScope_ = pg_->scope_;
57     pg_->scope_ = scope;
58 
59     for (const auto &[_, var] : scope->Bindings()) {
60         (void)_;
61         if (!var->LexicalBound() && var->IsLocalVariable()) {
62             var->AsLocalVariable()->BindVReg(pg->AllocReg());
63         }
64     }
65 
66     auto *debugInfo = &pg_->debugInfo_.variableDebugInfo;
67     if (pg_->IsDebug() && std::find(debugInfo->begin(), debugInfo->end(), pg_->scope_) == debugInfo->end()) {
68         debugInfo->push_back(pg_->scope_);
69     }
70     insStartIndex_ = pg_->insns_.size();
71 
72     Hoisting::Hoist(pg_);
73 }
74 
~LocalRegScope()75 LocalRegScope::~LocalRegScope() noexcept
76 {
77     if (!prevScope_) {
78         return;
79     }
80 
81     DebuggerCloseScope();
82 
83     pg_->scope_ = prevScope_;
84 }
85 
86 // FunctionRegScope
87 
FunctionRegScope(PandaGen * pg)88 FunctionRegScope::FunctionRegScope(PandaGen *pg) : RegScope(pg), envScope_(pg->Allocator()->New<EnvScope>())
89 {
90     ASSERT(pg_->Scope()->IsFunctionVariableScope());
91     ASSERT(pg_->NextReg() == binder::Binder::MANDATORY_PARAM_FUNC_REG);
92 
93     const auto *funcScope = pg_->Scope()->AsFunctionVariableScope();
94 
95     for (auto *param : funcScope->ParamScope()->Params()) {
96         VReg paramReg = pg_->AllocReg();
97         if (!param->LexicalBound()) {
98             param->BindVReg(paramReg);
99         }
100     }
101 
102     envScope_->Initialize(pg_);
103 
104     for (const auto &[_, var] : funcScope->Bindings()) {
105         (void)_;
106         if (var->Declaration()->IsParameterDecl()) {
107             continue;
108         }
109 
110         if (!var->LexicalBound() && var->IsLocalVariable()) {
111             var->AsLocalVariable()->BindVReg(pg->AllocReg());
112         }
113     }
114 
115     if (pg_->IsDebug()) {
116         pg_->debugInfo_.variableDebugInfo.push_back(funcScope);
117     }
118 
119     pg_->SetSourceLocationFlag(lexer::SourceLocationFlag::INVALID_SOURCE_LOCATION);
120     pg_->LoadAccFromArgs(pg_->rootNode_);
121 
122     Hoisting::Hoist(pg);
123     pg_->SetSourceLocationFlag(lexer::SourceLocationFlag::VALID_SOURCE_LOCATION);
124 }
125 
~FunctionRegScope()126 FunctionRegScope::~FunctionRegScope() noexcept
127 {
128     if (pg_->IsDebug()) {
129         pg_->topScope_->SetScopeStart(pg_->insns_.front());
130     }
131 
132     DebuggerCloseScope();
133 
134     envScope_->~EnvScope();
135 }
136 
137 }  // namespace panda::es2panda::compiler
138