1 /* 2 * Copyright (c) 2021 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_TYPE_LOWERING_H 17 #define ECMASCRIPT_COMPILER_TYPE_LOWERING_H 18 19 #include "ecmascript/compiler/argument_accessor.h" 20 #include "ecmascript/compiler/bytecode_circuit_builder.h" 21 #include "ecmascript/compiler/circuit_builder-inl.h" 22 23 namespace panda::ecmascript::kungfu { 24 // TypeLowering Process 25 // SW: state wire, DW: depend wire, VW: value wire 26 // Before Type Lowering: 27 // SW DW VW 28 // | | | 29 // | | | 30 // v v v 31 // +-------------------+ 32 // | (HIR) | SW +--------------+ 33 // --DW| JS_BYTECODE |---------->| IF_EXCEPTION | 34 // | +-------------------+ +--------------+ 35 // | SW VW 36 // | | | 37 // | v | 38 // | +--------------+ | 39 // | | IF_SUCCESS | | 40 // | +--------------+ | 41 // | SW | 42 // | | | 43 // | v v 44 // | +-------------------+ 45 // | | (HIR) | 46 // --->| JS_BYTECODE | 47 // +-------------------+ 48 // 49 // After Type Lowering: 50 // SW 51 // | 52 // v 53 // +-------------------+ 54 // | IF_BRANCH | 55 // | (Type Check) | 56 // +-------------------+ 57 // SW SW 58 // | | 59 // V V 60 // +--------------+ +--------------+ 61 // | IF_TRUE | | IF_FALSE | 62 // +--------------+ +--------------+ 63 // VW DW SW SW DW VW 64 // | | | | | | 65 // | | V V | | 66 // | | +---------------+ +---------------------+ | | 67 // ------->| FAST PATH | | (HIR) |<------- 68 // +---------------+ | JS_BYTECODE | 69 // VW DW SW +---------------------+ 70 // | | | SW VW DW 71 // | | | | | | 72 // | | | v | | 73 // | | | +--------------+ | | 74 // | | | | IF_SUCCESS | | | 75 // | | | +--------------+ | | 76 // | | | SW | | 77 // | | | | | | 78 // | | v v | | 79 // | | +---------------------+ | | 80 // | | | MERGE | | | 81 // | | +---------------------+ | | 82 // | | SW SW SW | | 83 // ----|----|----------|-----|-- | | 84 // ---|----|----------|-----|-|-------|---- 85 // | | | | | | | 86 // v v v | v v v 87 // +-----------------+ | +----------------+ 88 // | DEPEND_SELECTOR | | | VALUE_SELECTOR | 89 // +-----------------+ | +----------------+ 90 // DW | VW 91 // | | | 92 // v v v 93 // +------------------------+ 94 // | (HIR) | 95 // | JS_BYTECODE | 96 // +------------------------+ 97 98 class TypeLowering { 99 public: TypeLowering(Circuit * circuit,CompilationConfig * cmpCfg,TSManager * tsManager,bool enableLog,const std::string & name)100 TypeLowering(Circuit *circuit, CompilationConfig *cmpCfg, TSManager *tsManager, 101 bool enableLog, const std::string& name) 102 : circuit_(circuit), acc_(circuit), builder_(circuit, cmpCfg), 103 dependEntry_(circuit->GetDependRoot()), tsManager_(tsManager), 104 enableLog_(enableLog), methodName_(name) {} 105 106 ~TypeLowering() = default; 107 108 void RunTypeLowering(); 109 110 private: IsLogEnabled()111 bool IsLogEnabled() const 112 { 113 return enableLog_; 114 } 115 GetMethodName()116 const std::string& GetMethodName() const 117 { 118 return methodName_; 119 } 120 121 void Lower(GateRef gate); 122 void LowerType(GateRef gate); 123 void LowerPrimitiveTypeCheck(GateRef gate); 124 void LowerTypedBinaryOp(GateRef gate); 125 void LowerTypeConvert(GateRef gate); 126 void LowerTypedUnaryOp(GateRef gate); 127 void LowerTypedAdd(GateRef gate); 128 void LowerTypedSub(GateRef gate); 129 void LowerTypedMul(GateRef gate); 130 void LowerTypedMod(GateRef gate); 131 void LowerTypedLess(GateRef gate); 132 void LowerTypedLessEq(GateRef gate); 133 void LowerTypedGreater(GateRef gate); 134 void LowerTypedGreaterEq(GateRef gate); 135 void LowerTypedDiv(GateRef gate); 136 void LowerTypedEq(GateRef gate); 137 void LowerTypedNotEq(GateRef gate); 138 void LowerTypedShl(GateRef gate); 139 void LowerTypedShr(GateRef gate); 140 void LowerTypedAshr(GateRef gate); 141 void LowerTypedAnd(GateRef gate); 142 void LowerTypedOr(GateRef gate); 143 void LowerTypedXor(GateRef gate); 144 void LowerTypedInc(GateRef gate, GateType valueType); 145 void LowerTypedDec(GateRef gate, GateType valueType); 146 void LowerTypedNeg(GateRef gate, GateType valueType); 147 void LowerTypedNot(GateRef gate, GateType valueType); 148 void LowerTypedToBool(GateRef gate, GateType valueType); 149 void LowerPrimitiveToNumber(GateRef dst, GateRef src, GateType srcType); 150 void LowerIntCheck(GateRef gate); 151 void LowerDoubleCheck(GateRef gate); 152 void LowerNumberCheck(GateRef gate); 153 void LowerBooleanCheck(GateRef gate); 154 void LowerNumberAdd(GateRef gate); 155 void LowerNumberSub(GateRef gate); 156 void LowerNumberMul(GateRef gate); 157 void LowerNumberMod(GateRef gate); 158 void LowerNumberLess(GateRef gate); 159 void LowerNumberLessEq(GateRef gate); 160 void LowerNumberGreater(GateRef gate); 161 void LowerNumberGreaterEq(GateRef gate); 162 void LowerNumberDiv(GateRef gate); 163 void LowerNumberEq(GateRef gate); 164 void LowerNumberNotEq(GateRef gate); 165 void LowerNumberShl(GateRef gate); 166 void LowerNumberShr(GateRef gate); 167 void LowerNumberAshr(GateRef gate); 168 void LowerNumberAnd(GateRef gate); 169 void LowerNumberOr(GateRef gate); 170 void LowerNumberXor(GateRef gate); 171 void LowerNumberInc(GateRef gate, GateType valueType); 172 void LowerNumberDec(GateRef gate, GateType valueType); 173 void LowerNumberNeg(GateRef gate, GateType valueType); 174 void LowerNumberNot(GateRef gate, GateType valueType); 175 void LowerNumberToBool(GateRef gate, GateType valueType); 176 void LowerBooleanToBool(GateRef gate); 177 void LowerIndexCheck(GateRef gate); 178 void LowerOverflowCheck(GateRef gate); 179 void LowerTypedIncOverflowCheck(GateRef gate); 180 void LowerTypedDecOverflowCheck(GateRef gate); 181 void LowerTypedNegOverflowCheck(GateRef gate); 182 void LowerObjectTypeCheck(GateRef gate); 183 void LowerClassInstanceCheck(GateRef gate); 184 void LowerFloat32ArrayCheck(GateRef gate, GateRef glue); 185 void LowerArrayCheck(GateRef gate, GateRef glue); 186 void LowerStableArrayCheck(GateRef gate, GateRef glue); 187 void LowerTypedArrayCheck(GateRef gate, GateRef glue); 188 void LowerFloat32ArrayIndexCheck(GateRef gate); 189 void LowerArrayIndexCheck(GateRef gate); 190 void LowerLoadProperty(GateRef gate, GateRef glue); 191 void LowerStoreProperty(GateRef gate, GateRef glue); 192 void LowerLoadArrayLength(GateRef gate); 193 void LowerStoreElement(GateRef gate, GateRef glue); 194 void LowerLoadElement(GateRef gate); 195 void LowerArrayLoadElement(GateRef gate); 196 void LowerFloat32ArrayLoadElement(GateRef gate); 197 void LowerFloat32ArrayStoreElement(GateRef gate, GateRef glue); 198 void LowerHeapAllocate(GateRef gate, GateRef glue); 199 void LowerHeapAllocateInYoung(GateRef gate, GateRef glue); 200 void InitializeWithSpeicalValue(Label *exit, GateRef object, GateRef glue, GateRef value, 201 GateRef start, GateRef end); 202 void LowerTypedCallBuitin(GateRef gate); 203 void LowerCallTargetCheck(GateRef gate); 204 void LowerTypedNewAllocateThis(GateRef gate, GateRef glue); 205 void LowerTypedSuperAllocateThis(GateRef gate, GateRef glue); 206 void LowerGetSuperConstructor(GateRef gate); 207 208 GateRef LowerCallRuntime(GateRef glue, int index, const std::vector<GateRef> &args, bool useLabel = false); 209 210 template<OpCode Op> 211 GateRef CalculateNumbers(GateRef left, GateRef right, GateType leftType, GateType rightType); 212 template<OpCode Op> 213 GateRef ShiftNumber(GateRef left, GateRef right, GateType leftType, GateType rightType); 214 template<OpCode Op> 215 GateRef LogicalNumbers(GateRef left, GateRef right, GateType leftType, GateType rightType); 216 template<TypedBinOp Op> 217 GateRef CompareNumbers(GateRef left, GateRef right, GateType leftType, GateType rightType); 218 template<TypedBinOp Op> 219 GateRef CompareInt(GateRef left, GateRef right); 220 template<TypedBinOp Op> 221 GateRef CompareDouble(GateRef left, GateRef right); 222 template<TypedUnOp Op> 223 GateRef MonocularNumber(GateRef value, GateType valueType); 224 template<OpCode Op, MachineType Type> 225 GateRef BinaryOp(GateRef x, GateRef y); 226 GateRef DoubleToTaggedDoublePtr(GateRef gate); 227 GateRef ChangeInt32ToFloat64(GateRef gate); 228 GateRef TruncDoubleToInt(GateRef gate); 229 GateRef Int32Mod(GateRef left, GateRef right); 230 GateRef DoubleMod(GateRef left, GateRef right); 231 GateRef IntToTaggedIntPtr(GateRef x); 232 GateRef Less(GateRef left, GateRef right); 233 GateRef LessEq(GateRef left, GateRef right); 234 GateRef FastDiv(GateRef left, GateRef right); 235 GateRef ModNumbers(GateRef left, GateRef right, GateType leftType, GateType rightType); 236 GateRef DivNumbers(GateRef left, GateRef right, GateType leftType, GateType rightType); 237 GateRef FastEqual(GateRef left, GateRef right); 238 GateType GetLeftType(GateRef gate); 239 GateType GetRightType(GateRef gate); 240 GateRef GetConstPool(GateRef jsFunc); 241 GateRef GetObjectFromConstPool(GateRef jsFunc, GateRef index); GetFrameState(GateRef gate)242 GateRef GetFrameState(GateRef gate) const 243 { 244 return acc_.GetFrameState(gate); 245 } 246 247 Circuit *circuit_; 248 GateAccessor acc_; 249 CircuitBuilder builder_; 250 GateRef dependEntry_; 251 [[maybe_unused]] TSManager *tsManager_ {nullptr}; 252 bool enableLog_ {false}; 253 std::string methodName_; 254 }; 255 } // panda::ecmascript::kungfu 256 #endif // ECMASCRIPT_COMPILER_TYPE_LOWERING_H 257