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 #ifndef ES2PANDA_COMPILER_CORE_ENV_SCOPE_H 17 #define ES2PANDA_COMPILER_CORE_ENV_SCOPE_H 18 19 #include <binder/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 panda::es2panda::ir { 26 class AstNode; 27 class Statement; 28 } // namespace panda::es2panda::ir 29 30 namespace panda::es2panda::compiler { 31 32 class PandaGen; 33 34 class ScopeContext { 35 public: 36 explicit ScopeContext(PandaGen *pg, binder::Scope *newScope); 37 ~ScopeContext(); 38 39 NO_COPY_SEMANTIC(ScopeContext); 40 NO_MOVE_SEMANTIC(ScopeContext); 41 42 private: 43 PandaGen *pg_; 44 binder::Scope *prevScope_; 45 }; 46 47 class EnvScope { 48 public: 49 explicit EnvScope() = default; 50 51 NO_COPY_SEMANTIC(EnvScope); 52 NO_MOVE_SEMANTIC(EnvScope); 53 ~EnvScope(); 54 55 void Initialize(PandaGen *pg); 56 Prev()57 EnvScope *Prev() const 58 { 59 return prev_; 60 } 61 62 protected: 63 friend class PandaGen; 64 65 PandaGen *pg_ {}; 66 EnvScope *prev_ {}; 67 }; 68 69 class LoopEnvScope : public EnvScope { 70 public: LoopEnvScope(PandaGen * pg,binder::LoopScope * scope,LabelTarget target)71 explicit LoopEnvScope(PandaGen *pg, binder::LoopScope *scope, LabelTarget target) 72 : scope_(NeedEnv(scope) ? scope : nullptr), regScope_(pg, scope), lexEnvCtx_(this, pg, target) 73 { 74 InitLoopContext(pg, scope); 75 } 76 LoopEnvScope(PandaGen * pg,LabelTarget target,binder::LoopScope * scope)77 explicit LoopEnvScope(PandaGen *pg, LabelTarget target, binder::LoopScope *scope) 78 : scope_(NeedEnv(scope) ? scope : nullptr), regScope_(pg), lexEnvCtx_(this, pg, target) 79 { 80 InitLoopContext(pg, scope); 81 } 82 Scope()83 binder::VariableScope *Scope() const 84 { 85 ASSERT(HasEnv()); 86 return scope_; 87 } 88 HasEnv()89 bool HasEnv() const 90 { 91 return scope_ != nullptr; 92 } 93 94 void CopyPerIterationCtx(); 95 96 void PopLexEnvBeforeTheNextIter(); 97 98 private: NeedEnv(binder::VariableScope * scope)99 static bool NeedEnv(binder::VariableScope *scope) 100 { 101 return scope->IsVariableScope() && scope->AsVariableScope()->NeedLexEnv(); 102 } 103 104 void InitLoopContext(PandaGen *pg, binder::VariableScope *scope); 105 106 binder::VariableScope *scope_ {}; 107 LocalRegScope regScope_; 108 LexEnvContext lexEnvCtx_; 109 }; 110 111 } // namespace panda::es2panda::compiler 112 113 #endif 114