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 25 namespace ark::es2panda::ir { 26 class AstNode; 27 class Statement; 28 } // namespace ark::es2panda::ir 29 30 namespace ark::es2panda::compiler { 31 class PandaGen; 32 33 class ScopeContext { 34 public: 35 explicit ScopeContext(CodeGen *cg, varbinder::Scope *newScope); 36 ~ScopeContext(); 37 38 NO_COPY_SEMANTIC(ScopeContext); 39 NO_MOVE_SEMANTIC(ScopeContext); 40 41 private: 42 CodeGen *cg_; 43 varbinder::Scope *prevScope_; 44 }; 45 46 class EnvScope { 47 public: 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 LexEnv()56 VReg LexEnv() const 57 { 58 return lexEnv_; 59 } 60 Prev()61 EnvScope *Prev() const 62 { 63 return prev_; 64 } 65 66 protected: 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 76 class LoopEnvScope : public EnvScope { 77 public: LoopEnvScope(PandaGen * pg,varbinder::LoopScope * scope,LabelTarget target)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 LoopEnvScope(PandaGen * pg,LabelTarget target,varbinder::LoopScope * scope)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 LoopEnvScope(PandaGen * pg,varbinder::LoopDeclarationScope * scope)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 Scope()96 varbinder::VariableScope *Scope() const 97 { 98 ASSERT(HasEnv()); 99 return scope_; 100 } 101 HasEnv()102 bool HasEnv() const 103 { 104 return scope_ != nullptr; 105 } 106 107 void CopyPetIterationCtx(); 108 109 private: NeedEnv(varbinder::VariableScope * scope)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