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