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 27namespace panda::ecmascript::kungfu { 28class RangeGuard : public PassVisitor { 29public: 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; 41private: 42 43 DependChains* GetDependChain(GateRef dependIn) 44 { 45 size_t idx = acc_.GetId(dependIn); 46 ASSERT(idx <= circuit_->GetMaxGateId()); 47 return dependChains_[idx]; 48 } 49 50 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 62 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