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_CHECKER_ETS_BASE_ANALYZER_H 17 #define ES2PANDA_COMPILER_CHECKER_ETS_BASE_ANALYZER_H 18 19 #include "utils/arena_containers.h" 20 #include "util/enumbitops.h" 21 22 namespace panda::es2panda::ir { 23 class AstNode; 24 enum class AstNodeType; 25 } // namespace panda::es2panda::ir 26 27 namespace panda::es2panda::checker { 28 class ETSChecker; 29 30 enum class LivenessStatus { DEAD, ALIVE }; 31 DEFINE_BITOPS(LivenessStatus)32DEFINE_BITOPS(LivenessStatus) 33 34 class PendingExit { 35 public: 36 using JumpResolver = std::function<void()>; 37 38 explicit PendingExit( 39 const ir::AstNode *node, JumpResolver jumpResolver = [] {}) 40 : node_(node), jumpResolver_(std::move(jumpResolver)) 41 { 42 } 43 ~PendingExit() = default; 44 45 DEFAULT_COPY_SEMANTIC(PendingExit); 46 DEFAULT_NOEXCEPT_MOVE_SEMANTIC(PendingExit); 47 48 void ResolveJump() const 49 { 50 jumpResolver_(); 51 } 52 53 const ir::AstNode *Node() const 54 { 55 return node_; 56 } 57 58 private: 59 const ir::AstNode *node_; 60 JumpResolver jumpResolver_; 61 }; 62 63 using PendingExitsVector = std::vector<PendingExit>; 64 65 class BaseAnalyzer { 66 public: 67 explicit BaseAnalyzer() = default; 68 69 virtual void MarkDead() = 0; 70 RecordExit(const PendingExit & pe)71 void RecordExit(const PendingExit &pe) 72 { 73 pendingExits_.push_back(pe); 74 MarkDead(); 75 } 76 From(bool value)77 LivenessStatus From(bool value) 78 { 79 return value ? LivenessStatus::ALIVE : LivenessStatus::DEAD; 80 } 81 82 LivenessStatus ResolveJump(const ir::AstNode *node, ir::AstNodeType jumpKind); 83 LivenessStatus ResolveContinues(const ir::AstNode *node); 84 LivenessStatus ResolveBreaks(const ir::AstNode *node); 85 const ir::AstNode *GetJumpTarget(const ir::AstNode *node) const; 86 87 protected: 88 void ClearPendingExits(); 89 PendingExitsVector &PendingExits(); 90 void SetPendingExits(const PendingExitsVector &pendingExits); 91 PendingExitsVector &OldPendingExits(); 92 void SetOldPendingExits(const PendingExitsVector &oldPendingExits); 93 94 private: 95 PendingExitsVector pendingExits_; 96 PendingExitsVector oldPendingExits_; 97 }; 98 } // namespace panda::es2panda::checker 99 #endif 100