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_SLOWPATH_LOWERING_H 17 #define ECMASCRIPT_COMPILER_SLOWPATH_LOWERING_H 18 19 #include "ecmascript/compiler/argument_accessor.h" 20 #include "ecmascript/compiler/bytecode_circuit_builder.h" 21 #include "ecmascript/compiler/circuit.h" 22 #include "ecmascript/compiler/circuit_builder.h" 23 #include "ecmascript/compiler/circuit_builder-inl.h" 24 #include "ecmascript/compiler/gate_accessor.h" 25 26 namespace panda::ecmascript::kungfu { 27 // slowPath Lowering Process 28 // SW: state wire, DW: depend wire, VW: value wire 29 // Before lowering: 30 // SW DW VW 31 // | | | 32 // | | | 33 // v v v 34 // +-----------------------------+ 35 // | (HIR) | 36 // | JS_BYTECODE |DW-------------------------------------- 37 // | | | 38 // +-----------------------------+ | 39 // SW SW | 40 // | | | 41 // | | | 42 // | | | 43 // v v | 44 // +--------------+ +--------------+ | 45 // | IF_SUCCESS | | IF_EXCEPTION |SW--------- | 46 // +--------------+ +--------------+ | | 47 // SW SW | | 48 // | | | | 49 // v v | | 50 // --------------------------------------------------------------|-----------------------|------------------- 51 // catch processing | | 52 // | | 53 // v V 54 // +--------------+ +-----------------+ 55 // | MERGE |SW---->| DEPEND_SELECTOR | 56 // +--------------+ +-----------------+ 57 // DW 58 // | 59 // v 60 // +-----------------+ 61 // | GET_EXCEPTION | 62 // +-----------------+ 63 64 65 // After lowering: 66 // SW DW VW 67 // | | | 68 // | | | 69 // | v v 70 // | +---------------------+ +------------------+ 71 // | | CONSTANT(Exception) | | CALL |DW--------------- 72 // | +---------------------+ +------------------+ | 73 // | VW VW | 74 // | | | | 75 // | | | | 76 // | v v | 77 // | +------------------+ | 78 // | | EQ | | 79 // | +------------------+ | 80 // | VW | 81 // | | | 82 // | | | 83 // | v | 84 // | +------------------+ | 85 // ------------------------>| IF_BRANCH | | 86 // +------------------+ | 87 // SW SW | 88 // | | | 89 // v v | 90 // +--------------+ +--------------+ | 91 // | IF_FALSE | | IF_TRUE | | 92 // | (success) | | (exception) | | 93 // +--------------+ +--------------+ | 94 // SW SW SW | 95 // | | | | 96 // v v | | 97 // ---------------------------------------------------|-----------------------------|---------------------- 98 // catch processing | | 99 // | | 100 // v v 101 // +--------------+ +-----------------+ 102 // | MERGE |SW---------->| DEPEND_SELECTOR | 103 // +--------------+ +-----------------+ 104 // DW 105 // | 106 // v 107 // +-----------------+ 108 // | GET_EXCEPTION | 109 // +-----------------+ 110 111 class SlowPathLowering { 112 public: SlowPathLowering(Circuit * circuit,CompilationConfig * cmpCfg,TSManager * tsManager,const MethodLiteral * methodLiteral,bool enableLog,const std::string & name)113 SlowPathLowering(Circuit *circuit, CompilationConfig *cmpCfg, 114 TSManager *tsManager, const MethodLiteral *methodLiteral, 115 bool enableLog, const std::string& name) 116 : tsManager_(tsManager), methodLiteral_(methodLiteral), 117 circuit_(circuit), acc_(circuit), 118 argAcc_(circuit), builder_(circuit, cmpCfg), 119 enableLog_(enableLog), methodName_(name), glue_(acc_.GetGlueFromArgList()) 120 { 121 traceBc_ = cmpCfg->IsTraceBC(); 122 profiling_ = cmpCfg->IsProfiling(); 123 stressDeopt_ = cmpCfg->IsStressDeopt(); 124 } 125 ~SlowPathLowering() = default; 126 void CallRuntimeLowering(); 127 IsLogEnabled()128 bool IsLogEnabled() const 129 { 130 return enableLog_; 131 } 132 IsTraceBC()133 bool IsTraceBC() const 134 { 135 return traceBc_; 136 } 137 IsProfiling()138 bool IsProfiling() const 139 { 140 return profiling_; 141 } 142 IsStressDeopt()143 bool IsStressDeopt() const 144 { 145 return stressDeopt_; 146 } 147 148 private: GetMethodName()149 const std::string& GetMethodName() const 150 { 151 return methodName_; 152 } 153 154 void ReplaceHirWithPendingException(GateRef hirGate, GateRef state, GateRef depend, GateRef value); 155 void ReplaceHirWithValue(GateRef hirGate, GateRef value, bool noThrow = false); 156 void ReplaceHirToThrowCall(GateRef hirGate, GateRef callGate); 157 void LowerExceptionHandler(GateRef hirGate); 158 void Lower(GateRef gate); 159 void LowerAdd2(GateRef gate); 160 void LowerCreateIterResultObj(GateRef gate); 161 void SaveFrameToContext(GateRef gate); 162 void LowerSuspendGenerator(GateRef gate); 163 void LowerAsyncFunctionAwaitUncaught(GateRef gate); 164 void LowerAsyncFunctionResolve(GateRef gate); 165 void LowerAsyncFunctionReject(GateRef gate); 166 void LowerStGlobalVar(GateRef gate); 167 void LowerTryLdGlobalByName(GateRef gate); 168 void LowerGetIterator(GateRef gate); 169 void LowerGetAsyncIterator(GateRef gate); 170 void LowerToJSCall(GateRef hirGate, const std::vector<GateRef> &args, const std::vector<GateRef> &argsFastCall); 171 void LowerFastCall(GateRef gate, GateRef glue, GateRef func, GateRef argc, const std::vector<GateRef> &args, 172 const std::vector<GateRef> &fastCallArgs, Variable *result, Label *exit, bool isNew); 173 void LowerCallArg0(GateRef gate); 174 void LowerCallArg1Imm8V8(GateRef gate); 175 void LowerCallThisArg1(GateRef gate); 176 void LowerCallargs2Imm8V8V8(GateRef gate); 177 void LowerCallthis2Imm8V8V8V8(GateRef gate); 178 void LowerCallthis0Imm8V8(GateRef gate); 179 void LowerCallargs3Imm8V8V8(GateRef gate); 180 void LowerCallthis3Imm8V8V8V8V8(GateRef gate); 181 void LowerCallthisrangeImm8Imm8V8(GateRef gate); 182 void LowerWideCallthisrangePrefImm16V8(GateRef gate); 183 void LowerCallSpread(GateRef gate); 184 void LowerCallrangeImm8Imm8V8(GateRef gate); 185 void LowerWideCallrangePrefImm16V8(GateRef gate); 186 void LowerNewObjApply(GateRef gate); 187 void LowerThrow(GateRef gate); 188 void LowerThrowConstAssignment(GateRef gate); 189 void LowerThrowThrowNotExists(GateRef gate); 190 void LowerThrowPatternNonCoercible(GateRef gate); 191 void LowerThrowIfNotObject(GateRef gate); 192 void LowerThrowUndefinedIfHole(GateRef gate); 193 void LowerThrowUndefinedIfHoleWithName(GateRef gate); 194 void LowerThrowIfSuperNotCorrectCall(GateRef gate); 195 void LowerThrowDeleteSuperProperty(GateRef gate); 196 void LowerLdSymbol(GateRef gate); 197 void LowerLdGlobal(GateRef gate); 198 void LowerSub2(GateRef gate); 199 void LowerMul2(GateRef gate); 200 void LowerDiv2(GateRef gate); 201 void LowerMod2(GateRef gate); 202 void LowerEq(GateRef gate); 203 void LowerNotEq(GateRef gate); 204 void LowerLess(GateRef gate); 205 void LowerLessEq(GateRef gate); 206 void LowerGreater(GateRef gate); 207 void LowerGreaterEq(GateRef gate); 208 void LowerGetPropIterator(GateRef gate); 209 void LowerCloseIterator(GateRef gate); 210 void LowerInc(GateRef gate); 211 void LowerDec(GateRef gate); 212 void LowerToNumber(GateRef gate); 213 void LowerNeg(GateRef gate); 214 void LowerNot(GateRef gate); 215 void LowerShl2(GateRef gate); 216 void LowerShr2(GateRef gate); 217 void LowerAshr2(GateRef gate); 218 void LowerAnd2(GateRef gate); 219 void LowerOr2(GateRef gate); 220 void LowerXor2(GateRef gate); 221 void LowerDelObjProp(GateRef gate); 222 void LowerExp(GateRef gate); 223 void LowerIsIn(GateRef gate); 224 void LowerInstanceof(GateRef gate); 225 void LowerFastStrictNotEqual(GateRef gate); 226 void LowerFastStrictEqual(GateRef gate); 227 void LowerCreateEmptyArray(GateRef gate); 228 void LowerCreateEmptyObject(GateRef gate); 229 void LowerCreateArrayWithBuffer(GateRef gate); 230 void LowerCreateObjectWithBuffer(GateRef gate); 231 void LowerStModuleVar(GateRef gate); 232 void LowerGetTemplateObject(GateRef gate); 233 void LowerSetObjectWithProto(GateRef gate); 234 void LowerLdBigInt(GateRef gate); 235 void LowerToNumeric(GateRef gate); 236 void LowerDynamicImport(GateRef gate); 237 void LowerLdLocalModuleVarByIndex(GateRef gate); 238 void LowerExternalModule(GateRef gate); 239 void LowerGetModuleNamespace(GateRef gate); 240 void LowerSuperCall(GateRef gate); 241 void LowerSuperCallArrow(GateRef gate); 242 void LowerSuperCallSpread(GateRef gate); 243 void LowerIsTrueOrFalse(GateRef gate, bool flag); 244 void LowerNewObjRange(GateRef gate); 245 void LowerConditionJump(GateRef gate, bool isEqualJump); 246 void LowerGetNextPropName(GateRef gate); 247 void LowerCopyDataProperties(GateRef gate); 248 void LowerCreateObjectWithExcludedKeys(GateRef gate); 249 void LowerCreateRegExpWithLiteral(GateRef gate); 250 void LowerStOwnByValue(GateRef gate); 251 void LowerStOwnByIndex(GateRef gate); 252 void LowerStOwnByName(GateRef gate); 253 void LowerDefineFunc(GateRef gate); 254 void LowerNewLexicalEnv(GateRef gate); 255 void LowerNewLexicalEnvWithName(GateRef gate); 256 void LowerPopLexicalEnv(GateRef gate); 257 void LowerLdSuperByValue(GateRef gate); 258 void LowerStSuperByValue(GateRef gate); 259 void LowerTryStGlobalByName(GateRef gate); 260 void LowerStConstToGlobalRecord(GateRef gate, bool isConst); 261 void LowerStOwnByValueWithNameSet(GateRef gate); 262 void LowerStOwnByNameWithNameSet(GateRef gate); 263 void LowerLdGlobalVar(GateRef gate); 264 void LowerLdObjByName(GateRef gate); 265 void LowerStObjByName(GateRef gate, bool isThis); 266 void LowerLdSuperByName(GateRef gate); 267 void LowerStSuperByName(GateRef gate); 268 void LowerDefineGetterSetterByValue(GateRef gate); 269 void LowerLdObjByIndex(GateRef gate); 270 void LowerStObjByIndex(GateRef gate); 271 void LowerLdObjByValue(GateRef gate, bool isThis); 272 void LowerStObjByValue(GateRef gate, bool isThis); 273 void LowerCreateGeneratorObj(GateRef gate); 274 void LowerStArraySpread(GateRef gate); 275 void LowerLdLexVar(GateRef gate); 276 void LowerStLexVar(GateRef gate); 277 void LowerDefineClassWithBuffer(GateRef gate); 278 void LowerAsyncFunctionEnter(GateRef gate); 279 void LowerTypeof(GateRef gate); 280 void LowerResumeGenerator(GateRef gate); 281 void LowerStoreRegister(GateRef gate, GateRef arrayGate); 282 void LowerGetResumeMode(GateRef gate); 283 void LowerDefineMethod(GateRef gate); 284 void LowerGetUnmappedArgs(GateRef gate); 285 void LowerCopyRestArgs(GateRef gate); 286 void LowerCallStubWithIC(GateRef gate, int sign, const std::vector<GateRef> &args); 287 GateRef LowerCallRuntime(GateRef gate, int index, const std::vector<GateRef> &args, bool useLabel = false); 288 GateRef LowerCallNGCRuntime(GateRef gate, int index, const std::vector<GateRef> &args, bool useLabel = false); 289 void LowerCreateAsyncGeneratorObj(GateRef gate); 290 void LowerAsyncGeneratorResolve(GateRef gate); 291 void LowerAsyncGeneratorReject(GateRef gate); 292 void LowerSetGeneratorState(GateRef gate); 293 GateRef GetValueFromTaggedArray(GateRef arrayGate, GateRef indexOffset); 294 void AddProfiling(GateRef gate, bool skipGenerator = true); 295 GateRef FastStrictEqual(GateRef left, GateRef right); 296 void LowerWideLdPatchVar(GateRef gate); 297 void LowerWideStPatchVar(GateRef gate); 298 void LowerLdThisByName(GateRef gate); 299 void LowerConstruct(GateRef gate); 300 void LowerTypedCall(GateRef gate); 301 void LowerTypedFastCall(GateRef gate); 302 void LowerCheckSafePointAndStackOver(GateRef gate); 303 void LowerNotifyConcurrentResult(GateRef gate); 304 void LowerGetEnv(GateRef gate); 305 void DeleteLoopExit(GateRef gate); 306 void DeleteLoopExitValue(GateRef gate); 307 void LowerLdStr(GateRef gate); 308 309 TSManager *tsManager_ {nullptr}; 310 const MethodLiteral *methodLiteral_ {nullptr}; 311 Circuit *circuit_; 312 GateAccessor acc_; 313 ArgumentAccessor argAcc_; 314 CircuitBuilder builder_; 315 bool enableLog_ {false}; 316 bool traceBc_ {false}; 317 bool profiling_ {false}; 318 bool stressDeopt_ {false}; 319 std::string methodName_; 320 GateRef glue_ {Circuit::NullGate()}; 321 }; 322 } // panda::ecmascript::kungfu 323 #endif // ECMASCRIPT_COMPILER_SLOWPATH_LOWERING_H 324