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 dependEntry_(circuit->GetDependRoot()), 120 enableLog_(enableLog), methodName_(name), glue_(acc_.GetGlueFromArgList()) 121 { 122 traceBc_ = cmpCfg->IsTraceBC(); 123 profiling_ = cmpCfg->IsProfiling(); 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 143 private: GetMethodName()144 const std::string& GetMethodName() const 145 { 146 return methodName_; 147 } 148 149 GateAccessor::UseIterator ReplaceHirControlGate(const GateAccessor::UseIterator &useIt, GateRef newGate, 150 bool noThrow = false); 151 void ReplaceHirToSubCfg(GateRef hir, GateRef outir, 152 const std::vector<GateRef> &successControl, 153 const std::vector<GateRef> &exceptionControl, 154 bool noThrow = false); 155 void ExceptionReturn(GateRef state, GateRef depend); 156 void ReplaceHirWithIfBranch(GateRef hirGate, GateRef callGate, GateRef ifBranch); 157 void ReplaceHirToCall(GateRef hirGate, GateRef callGate, bool noThrow = false); 158 void ReplaceHirToJSCall(GateRef hirGate, GateRef callGate); 159 void ReplaceHirToThrowCall(GateRef hirGate, GateRef callGate); 160 void LowerExceptionHandler(GateRef hirGate); 161 // environment must be initialized 162 GateRef LoadObjectFromConstPool(GateRef jsFunc, GateRef index); 163 GateRef GetProfileTypeInfo(GateRef jsFunc); 164 // environment must be initialized 165 GateRef GetHomeObjectFromJSFunction(GateRef jsFunc); 166 void Lower(GateRef gate); 167 void LowerAdd2(GateRef gate); 168 void LowerCreateIterResultObj(GateRef gate); 169 void SaveFrameToContext(GateRef gate, GateRef jsFunc); 170 void LowerSuspendGenerator(GateRef gate, GateRef jsFunc); 171 void LowerAsyncFunctionAwaitUncaught(GateRef gate); 172 void LowerAsyncFunctionResolve(GateRef gate); 173 void LowerAsyncFunctionReject(GateRef gate); 174 void LowerLoadStr(GateRef gate, GateRef jsFunc); 175 void LowerStGlobalVar(GateRef gate, GateRef jsFunc); 176 void LowerTryLdGlobalByName(GateRef gate, GateRef jsFunc); 177 void LowerGetIterator(GateRef gate); 178 void LowerGetAsyncIterator(GateRef gate); 179 void LowerToJSCall(GateRef gate, const std::vector<GateRef> &args); 180 void LowerCallArg0(GateRef gate); 181 void LowerCallArg1Imm8V8(GateRef gate); 182 void LowerCallThisArg1(GateRef gate); 183 void LowerCallargs2Imm8V8V8(GateRef gate); 184 void LowerCallthis2Imm8V8V8V8(GateRef gate); 185 void LowerCallthis0Imm8V8(GateRef gate); 186 void LowerCallargs3Imm8V8V8(GateRef gate); 187 void LowerCallthis3Imm8V8V8V8V8(GateRef gate); 188 void LowerCallthisrangeImm8Imm8V8(GateRef gate); 189 void LowerWideCallthisrangePrefImm16V8(GateRef gate); 190 void LowerCallSpread(GateRef gate); 191 void LowerCallrangeImm8Imm8V8(GateRef gate); 192 void LowerWideCallrangePrefImm16V8(GateRef gate); 193 void LowerNewObjApply(GateRef gate); 194 void LowerThrow(GateRef gate); 195 void LowerThrowConstAssignment(GateRef gate); 196 void LowerThrowThrowNotExists(GateRef gate); 197 void LowerThrowPatternNonCoercible(GateRef gate); 198 void LowerThrowIfNotObject(GateRef gate); 199 void LowerThrowUndefinedIfHole(GateRef gate); 200 void LowerThrowUndefinedIfHoleWithName(GateRef gate, GateRef jsFunc); 201 void LowerThrowIfSuperNotCorrectCall(GateRef gate); 202 void LowerThrowDeleteSuperProperty(GateRef gate); 203 void LowerLdSymbol(GateRef gate); 204 void LowerLdGlobal(GateRef gate); 205 void LowerSub2(GateRef gate); 206 void LowerMul2(GateRef gate); 207 void LowerDiv2(GateRef gate); 208 void LowerMod2(GateRef gate); 209 void LowerEq(GateRef gate); 210 void LowerNotEq(GateRef gate); 211 void LowerLess(GateRef gate); 212 void LowerLessEq(GateRef gate); 213 void LowerGreater(GateRef gate); 214 void LowerGreaterEq(GateRef gate); 215 void LowerGetPropIterator(GateRef gate); 216 void LowerCloseIterator(GateRef gate); 217 void LowerInc(GateRef gate); 218 void LowerDec(GateRef gate); 219 void LowerToNumber(GateRef gate); 220 void LowerNeg(GateRef gate); 221 void LowerNot(GateRef gate); 222 void LowerShl2(GateRef gate); 223 void LowerShr2(GateRef gate); 224 void LowerAshr2(GateRef gate); 225 void LowerAnd2(GateRef gate); 226 void LowerOr2(GateRef gate); 227 void LowerXor2(GateRef gate); 228 void LowerDelObjProp(GateRef gate); 229 void LowerExp(GateRef gate); 230 void LowerIsIn(GateRef gate); 231 void LowerInstanceof(GateRef gate); 232 void LowerFastStrictNotEqual(GateRef gate); 233 void LowerFastStrictEqual(GateRef gate); 234 void LowerCreateEmptyArray(GateRef gate); 235 void LowerCreateEmptyObject(GateRef gate); 236 void LowerCreateArrayWithBuffer(GateRef gate, GateRef jsFunc); 237 void LowerCreateObjectWithBuffer(GateRef gate, GateRef jsFunc); 238 void LowerStModuleVar(GateRef gate, GateRef jsFunc); 239 void LowerGetTemplateObject(GateRef gate); 240 void LowerSetObjectWithProto(GateRef gate); 241 void LowerLdBigInt(GateRef gate); 242 void LowerToNumeric(GateRef gate); 243 void LowerDynamicImport(GateRef gate, GateRef jsFunc); 244 void LowerLdLocalModuleVarByIndex(GateRef gate, GateRef jsFunc); 245 void LowerExternalModule(GateRef gate, GateRef jsFunc); 246 void LowerGetModuleNamespace(GateRef gate, GateRef jsFunc); 247 void LowerSuperCall(GateRef gate, GateRef func, GateRef newTarget); 248 void LowerSuperCallArrow(GateRef gate, GateRef newTarget); 249 void LowerSuperCallSpread(GateRef gate, GateRef newTarget); 250 void LowerIsTrueOrFalse(GateRef gate, bool flag); 251 void LowerNewObjRange(GateRef gate); 252 void LowerConditionJump(GateRef gate, bool isEqualJump); 253 void LowerGetNextPropName(GateRef gate); 254 void LowerCopyDataProperties(GateRef gate); 255 void LowerCreateObjectWithExcludedKeys(GateRef gate); 256 void LowerCreateRegExpWithLiteral(GateRef gate); 257 void LowerStOwnByValue(GateRef gate); 258 void LowerStOwnByIndex(GateRef gate); 259 void LowerStOwnByName(GateRef gate); 260 void LowerDefineFunc(GateRef gate, GateRef jsFunc); 261 void LowerNewLexicalEnv(GateRef gate); 262 void LowerNewLexicalEnvWithName(GateRef gate, GateRef jsFunc); 263 void LowerPopLexicalEnv(GateRef gate); 264 void LowerLdSuperByValue(GateRef gate, GateRef jsFunc); 265 void LowerStSuperByValue(GateRef gate, GateRef jsFunc); 266 void LowerTryStGlobalByName(GateRef gate, GateRef jsFunc); 267 void LowerStConstToGlobalRecord(GateRef gate, bool isConst); 268 void LowerStOwnByValueWithNameSet(GateRef gate); 269 void LowerStOwnByNameWithNameSet(GateRef gate); 270 void LowerLdGlobalVar(GateRef gate, GateRef jsFunc); 271 void LowerLdObjByName(GateRef gate, GateRef jsFunc); 272 void LowerStObjByName(GateRef gate, GateRef jsFunc, bool isThis); 273 void LowerLdSuperByName(GateRef gate, GateRef jsFunc); 274 void LowerStSuperByName(GateRef gate, GateRef jsFunc); 275 void LowerDefineGetterSetterByValue(GateRef gate); 276 void LowerLdObjByIndex(GateRef gate); 277 void LowerStObjByIndex(GateRef gate); 278 void LowerLdObjByValue(GateRef gate, GateRef jsFunc, bool isThis); 279 void LowerStObjByValue(GateRef gate, GateRef jsFunc, bool isThis); 280 void LowerCreateGeneratorObj(GateRef gate); 281 void LowerStArraySpread(GateRef gate); 282 void LowerLdLexVar(GateRef gate); 283 void LowerStLexVar(GateRef gate); 284 void LowerDefineClassWithBuffer(GateRef gate, GateRef jsFunc); 285 void LowerAsyncFunctionEnter(GateRef gate); 286 void LowerTypeof(GateRef gate); 287 void LowerResumeGenerator(GateRef gate); 288 void LowerGetResumeMode(GateRef gate); 289 void LowerDefineMethod(GateRef gate, GateRef jsFunc); 290 void LowerGetUnmappedArgs(GateRef gate, GateRef actualArgc); 291 void LowerCopyRestArgs(GateRef gate, GateRef actualArgc); 292 GateRef LowerCallRuntime(int index, const std::vector<GateRef> &args, bool useLabel = false); 293 GateRef LowerCallNGCRuntime(int index, const std::vector<GateRef> &args, bool useLabel = false); 294 int32_t ComputeCallArgc(GateRef gate, EcmaOpcode op); 295 void LowerCreateAsyncGeneratorObj(GateRef gate); 296 void LowerAsyncGeneratorResolve(GateRef gate); 297 void LowerAsyncGeneratorReject(GateRef gate); 298 void LowerSetGeneratorState(GateRef gate, GateRef jsFunc); 299 GateRef GetValueFromTaggedArray(GateRef arrayGate, GateRef indexOffset); 300 void AddProfiling(GateRef gate, bool skipGenerator = true); 301 GateRef FastStrictEqual(GateRef left, GateRef right); 302 void LowerWideLdPatchVar(GateRef gate); 303 void LowerWideStPatchVar(GateRef gate); 304 void LowerLdThisByName(GateRef gate, GateRef jsFunc); 305 void LowerConstPoolData(GateRef gate); 306 void LowerDeoptCheck(GateRef gate); 307 void LowerConstruct(GateRef gate); 308 void LowerUpdateHotness(GateRef gate); 309 void LowerNotifyConcurrentResult(GateRef gate); 310 311 TSManager *tsManager_ {nullptr}; 312 const MethodLiteral *methodLiteral_ {nullptr}; 313 Circuit *circuit_; 314 GateAccessor acc_; 315 ArgumentAccessor argAcc_; 316 CircuitBuilder builder_; 317 GateRef dependEntry_; 318 bool enableLog_ {false}; 319 bool traceBc_ {false}; 320 bool profiling_ {false}; 321 std::string methodName_; 322 GateRef glue_ {Circuit::NullGate()}; 323 }; 324 } // panda::ecmascript::kungfu 325 #endif // ECMASCRIPT_COMPILER_SLOWPATH_LOWERING_H 326