1/* 2 * Copyright (c) 2021 - 2023 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#ifndef ES2PANDA_COMPILER_CORE_ENV_SCOPE_H 17#define ES2PANDA_COMPILER_CORE_ENV_SCOPE_H 18 19#include "varbinder/scope.h" 20#include "ir/irnode.h" 21#include "compiler/core/dynamicContext.h" 22#include "compiler/core/regScope.h" 23#include "compiler/core/labelTarget.h" 24 25namespace ark::es2panda::ir { 26class AstNode; 27class Statement; 28} // namespace ark::es2panda::ir 29 30namespace ark::es2panda::compiler { 31class PandaGen; 32 33class ScopeContext { 34public: 35 explicit ScopeContext(CodeGen *cg, varbinder::Scope *newScope); 36 ~ScopeContext(); 37 38 NO_COPY_SEMANTIC(ScopeContext); 39 NO_MOVE_SEMANTIC(ScopeContext); 40 41private: 42 CodeGen *cg_; 43 varbinder::Scope *prevScope_; 44}; 45 46class EnvScope { 47public: 48 explicit EnvScope() = default; 49 50 NO_COPY_SEMANTIC(EnvScope); 51 NO_MOVE_SEMANTIC(EnvScope); 52 ~EnvScope(); 53 54 void Initialize(PandaGen *pg, VReg lexEnv); 55 56 VReg LexEnv() const 57 { 58 return lexEnv_; 59 } 60 61 EnvScope *Prev() const 62 { 63 return prev_; 64 } 65 66protected: 67 friend class PandaGen; 68 69 // NOLINTBEGIN(misc-non-private-member-variables-in-classes) 70 PandaGen *pg_ {}; 71 EnvScope *prev_ {}; 72 VReg lexEnv_ {}; 73 // NOLINTEND(misc-non-private-member-variables-in-classes) 74}; 75 76class LoopEnvScope : public EnvScope { 77public: 78 explicit LoopEnvScope(PandaGen *pg, varbinder::LoopScope *scope, LabelTarget target) 79 : scope_(NeedEnv(scope) ? scope : nullptr), regScope_(pg, scope), lexEnvCtx_(this, pg, target) 80 { 81 CopyBindings(pg, scope, varbinder::VariableFlags::PER_ITERATION); 82 } 83 84 explicit LoopEnvScope(PandaGen *pg, LabelTarget target, varbinder::LoopScope *scope) 85 : scope_(NeedEnv(scope) ? scope : nullptr), regScope_(pg), lexEnvCtx_(this, pg, target) 86 { 87 CopyBindings(pg, scope, varbinder::VariableFlags::PER_ITERATION); 88 } 89 90 explicit LoopEnvScope(PandaGen *pg, varbinder::LoopDeclarationScope *scope) 91 : scope_(NeedEnv(scope) ? scope : nullptr), regScope_(pg), lexEnvCtx_(this, pg, {}) 92 { 93 CopyBindings(pg, scope, varbinder::VariableFlags::LOOP_DECL); 94 } 95 96 varbinder::VariableScope *Scope() const 97 { 98 ASSERT(HasEnv()); 99 return scope_; 100 } 101 102 bool HasEnv() const 103 { 104 return scope_ != nullptr; 105 } 106 107 void CopyPetIterationCtx(); 108 109private: 110 static bool NeedEnv(varbinder::VariableScope *scope) 111 { 112 return scope->IsVariableScope() && scope->AsVariableScope()->NeedLexEnv(); 113 } 114 115 void CopyBindings(PandaGen *pg, varbinder::VariableScope *scope, varbinder::VariableFlags flag); 116 117 varbinder::VariableScope *scope_ {}; 118 LocalRegScope regScope_; 119 LexEnvContext lexEnvCtx_; 120}; 121} // namespace ark::es2panda::compiler 122 123#endif 124