• 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 <binder/binder.h>
19 #include <binder/scope.h>
20 #include <binder/variable.h>
21 #include <compiler/base/hoisting.h>
22 #include <compiler/core/compilerContext.h>
23 #include <compiler/core/pandagen.h>
24 
25 namespace panda::es2panda::compiler {
26 
27 // RegScope
28 
RegScope(PandaGen * pg)29 RegScope::RegScope(PandaGen *pg) : pg_(pg), regBase_(pg_->usedRegs_) {}
30 
~RegScope()31 RegScope::~RegScope()
32 {
33     pg_->totalRegs_ = std::max(pg_->totalRegs_, pg_->usedRegs_);
34     pg_->usedRegs_ = regBase_;
35 }
36 
DebuggerCloseScope()37 void RegScope::DebuggerCloseScope()
38 {
39     if (!pg_->IsDebug()) {
40         return;
41     }
42 
43     pg_->scope_->SetScopeEnd(pg_->insns_.back());
44 }
45 
46 // LocalRegScope
47 
LocalRegScope(PandaGen * pg)48 LocalRegScope::LocalRegScope(PandaGen *pg) : RegScope(pg) {}
49 
LocalRegScope(PandaGen * pg,binder::Scope * scope)50 LocalRegScope::LocalRegScope(PandaGen *pg, binder::Scope *scope) : RegScope(pg)
51 {
52     prevScope_ = pg_->scope_;
53     pg_->scope_ = scope;
54 
55     for (const auto &[_, var] : scope->Bindings()) {
56         (void)_;
57         if (!var->LexicalBound() && var->IsLocalVariable()) {
58             var->AsLocalVariable()->BindVReg(pg->AllocReg());
59         }
60     }
61 
62     if (pg_->IsDebug()) {
63         pg_->scope_->SetScopeStart(pg_->insns_.back());
64         pg_->debugInfo_.variableDebugInfo.push_back(pg_->scope_);
65     }
66 
67     Hoisting::Hoist(pg_);
68 }
69 
~LocalRegScope()70 LocalRegScope::~LocalRegScope()
71 {
72     if (!prevScope_) {
73         return;
74     }
75 
76     DebuggerCloseScope();
77 
78     pg_->scope_ = prevScope_;
79 }
80 
81 // FunctionRegScope
82 
FunctionRegScope(PandaGen * pg)83 FunctionRegScope::FunctionRegScope(PandaGen *pg) : RegScope(pg), envScope_(pg->Allocator()->New<EnvScope>())
84 {
85     ASSERT(pg_->Scope()->IsFunctionVariableScope());
86     ASSERT(pg_->NextReg() == binder::Binder::MANDATORY_PARAM_FUNC_REG);
87 
88     const auto *funcScope = pg_->Scope()->AsFunctionVariableScope();
89 
90     for (auto *param : funcScope->ParamScope()->Params()) {
91         VReg paramReg = pg_->AllocReg();
92         if (!param->LexicalBound()) {
93             param->BindVReg(paramReg);
94         }
95     }
96 
97     envScope_->Initialize(pg_);
98 
99     for (const auto &[_, var] : funcScope->Bindings()) {
100         (void)_;
101         if (var->Declaration()->IsParameterDecl()) {
102             continue;
103         }
104 
105         if (!var->LexicalBound() && var->IsLocalVariable()) {
106             var->AsLocalVariable()->BindVReg(pg->AllocReg());
107         }
108     }
109 
110     if (pg_->IsDebug()) {
111         pg_->debugInfo_.variableDebugInfo.push_back(funcScope);
112     }
113 
114     pg_->SetSourceLocationFlag(lexer::SourceLocationFlag::INVALID_SOURCE_LOCATION);
115     pg_->LoadAccFromArgs(pg_->rootNode_);
116 
117     Hoisting::Hoist(pg);
118     pg_->SetSourceLocationFlag(lexer::SourceLocationFlag::VALID_SOURCE_LOCATION);
119 }
120 
~FunctionRegScope()121 FunctionRegScope::~FunctionRegScope()
122 {
123     if (pg_->IsDebug()) {
124         pg_->topScope_->SetScopeStart(pg_->insns_.front());
125     }
126 
127     DebuggerCloseScope();
128 
129     envScope_->~EnvScope();
130 }
131 
132 }  // namespace panda::es2panda::compiler
133