1 /* 2 * Copyright (c) 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 ECMASCRIPT_COMPILER_RANGE_GUARD_H 17 #define ECMASCRIPT_COMPILER_RANGE_GUARD_H 18 19 #include "ecmascript/compiler/circuit_builder.h" 20 #include "ecmascript/compiler/gate_accessor.h" 21 #include "ecmascript/compiler/pass_manager.h" 22 #include "ecmascript/compiler/base/depend_chain_helper.h" 23 #include "ecmascript/mem/chunk_containers.h" 24 #include "ecmascript/compiler/number_gate_info.h" 25 #include "ecmascript/compiler/combined_pass_visitor.h" 26 27 namespace panda::ecmascript::kungfu { 28 class RangeGuard : public PassVisitor { 29 public: RangeGuard(Circuit* circuit, RPOVisitor* visitor, Chunk* chunk)30 RangeGuard(Circuit* circuit, RPOVisitor* visitor, Chunk* chunk) 31 : PassVisitor(circuit, chunk, visitor), circuit_(circuit), 32 builder_(circuit), acc_(circuit), dependChains_(chunk) {} 33 34 ~RangeGuard() = default; 35 36 void Initialize() override; 37 GateRef VisitGate(GateRef gate) override; 38 bool CheckInputSource(GateRef lhs, GateRef rhs); 39 uint32_t CheckIndexCheckLengthInput(GateRef lhs, GateRef rhs) const; 40 uint32_t CheckIndexCheckIndexInput(GateRef lhs, GateRef rhs) const; 41 private: 42 GetDependChain(GateRef dependIn)43 DependChains* GetDependChain(GateRef dependIn) 44 { 45 size_t idx = acc_.GetId(dependIn); 46 ASSERT(idx <= circuit_->GetMaxGateId()); 47 return dependChains_[idx]; 48 } 49 FoundIndexCheckedForLength(DependChains* dependChain, GateRef input) const50 uint32_t FoundIndexCheckedForLength(DependChains* dependChain, GateRef input) const 51 { 52 for (auto iter = dependChain->begin(); iter != dependChain->end(); ++iter) { 53 uint32_t length = CheckIndexCheckLengthInput(iter.GetCurrentGate(), input); 54 if (length > 0) { // found !!! 55 return length; 56 } 57 } 58 59 return 0; 60 } 61 FoundIndexCheckedForIndex(DependChains* dependChain, GateRef input) const62 uint32_t FoundIndexCheckedForIndex(DependChains* dependChain, GateRef input) const 63 { 64 for (auto iter = dependChain->begin(); iter != dependChain->end(); ++iter) { 65 uint32_t length = CheckIndexCheckIndexInput(iter.GetCurrentGate(), input); 66 if (length > 0) { // found !!! 67 return length; 68 } 69 } 70 71 return 0; 72 } 73 74 GateRef VisitDependEntry(GateRef gate); 75 GateRef UpdateDependChain(GateRef gate, DependChains* dependInfo); 76 GateRef TryApplyRangeGuardForLength(DependChains* dependInfo, GateRef gate, GateRef input); 77 GateRef TryApplyRangeGuardForIndex(DependChains* dependInfo, GateRef gate, GateRef input); 78 GateRef TryApplyRangeGuardGate(GateRef gate); 79 GateRef TraverseOthers(GateRef gate); 80 GateRef TraverseDependSelector(GateRef gate); 81 82 Circuit* circuit_; 83 CircuitBuilder builder_; 84 GateAccessor acc_; 85 ChunkVector<DependChains*> dependChains_; 86 87 friend class RangeInfo; 88 }; 89 } // panda::ecmascript::kungfu 90 #endif // ECMASCRIPT_COMPILER_RANGE_GUARD_H