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/circuit.h" 21 #include "ecmascript/compiler/circuit_builder.h" 22 #include "ecmascript/compiler/gate_accessor.h" 23 #include "ecmascript/compiler/pass_manager.h" 24 #include <cstddef> 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,PassContext * ctx,const MethodLiteral * methodLiteral,bool enableLog,const std::string & name)113 SlowPathLowering(Circuit *circuit, CompilationConfig *cmpCfg, 114 PassContext *ctx, const MethodLiteral *methodLiteral, 115 bool enableLog, const std::string& name) 116 : compilationEnv_(ctx->GetCompilationEnv()), 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 LowerNewFastCall(GateRef gate, GateRef glue, GateRef func, bool needPushArgv, 174 const std::vector<GateRef> &args, const std::vector<GateRef> &fastCallArgs, 175 Variable *result, Label *exit); 176 void LowerCallArg0(GateRef gate); 177 void LowerCallArg1Imm8V8(GateRef gate); 178 void LowerCallThisArg1(GateRef gate); 179 void LowerCallargs2Imm8V8V8(GateRef gate); 180 void LowerCallthis2Imm8V8V8V8(GateRef gate); 181 void LowerCallthis0Imm8V8(GateRef gate); 182 void LowerCallargs3Imm8V8V8(GateRef gate); 183 void LowerCallthis3Imm8V8V8V8V8(GateRef gate); 184 void LowerCallthisrangeImm8Imm8V8(GateRef gate); 185 void LowerWideCallthisrangePrefImm16V8(GateRef gate); 186 void LowerCallSpread(GateRef gate); 187 void LowerCallrangeImm8Imm8V8(GateRef gate); 188 void LowerWideCallrangePrefImm16V8(GateRef gate); 189 void LowerNewObjApply(GateRef gate); 190 void LowerThrow(GateRef gate); 191 void LowerThrowConstAssignment(GateRef gate); 192 void LowerThrowThrowNotExists(GateRef gate); 193 void LowerThrowPatternNonCoercible(GateRef gate); 194 void LowerThrowIfNotObject(GateRef gate); 195 void LowerThrowUndefinedIfHole(GateRef gate); 196 void LowerThrowUndefinedIfHoleWithName(GateRef Getgate); 197 void LowerThrowIfSuperNotCorrectCall(GateRef gate); 198 void LowerThrowDeleteSuperProperty(GateRef gate); 199 void LowerLdSymbol(GateRef gate); 200 void LowerLdGlobal(GateRef gate); 201 void LowerSub2(GateRef gate); 202 void LowerMul2(GateRef gate); 203 void LowerDiv2(GateRef gate); 204 void LowerMod2(GateRef gate); 205 void LowerEq(GateRef gate); 206 void LowerNotEq(GateRef gate); 207 void LowerLess(GateRef gate); 208 void LowerLessEq(GateRef gate); 209 void LowerGreater(GateRef gate); 210 void LowerGreaterEq(GateRef gate); 211 void LowerGetPropIterator(GateRef gate); 212 void LowerCloseIterator(GateRef gate); 213 void LowerInc(GateRef gate); 214 void LowerDec(GateRef gate); 215 void LowerToNumber(GateRef gate); 216 void LowerNeg(GateRef gate); 217 void LowerNot(GateRef gate); 218 void LowerShl2(GateRef gate); 219 void LowerShr2(GateRef gate); 220 void LowerAshr2(GateRef gate); 221 void LowerAnd2(GateRef gate); 222 void LowerOr2(GateRef gate); 223 void LowerXor2(GateRef gate); 224 void LowerDelObjProp(GateRef gate); 225 void LowerExp(GateRef gate); 226 void LowerIsIn(GateRef gate); 227 void LowerInstanceof(GateRef gate); 228 void LowerFastStrictNotEqual(GateRef gate); 229 void LowerFastStrictEqual(GateRef gate); 230 void LowerCreateEmptyArray(GateRef gate); 231 void LowerCreateEmptyObject(GateRef gate); 232 void LowerCreateArrayWithBuffer(GateRef gate); 233 void LowerCreateObjectWithBuffer(GateRef gate); 234 void LowerStModuleVar(GateRef gate); 235 void LowerGetTemplateObject(GateRef gate); 236 void LowerSetObjectWithProto(GateRef gate); 237 void LowerLdBigInt(GateRef gate); 238 void LowerToNumeric(GateRef gate); 239 void LowerDynamicImport(GateRef gate); 240 void LowerLdLocalModuleVarByIndex(GateRef gate); 241 void LowerExternalModule(GateRef gate); 242 void LowerGetModuleNamespace(GateRef gate); 243 void LowerSendableExternalModule(GateRef gate); 244 void LowerSuperCall(GateRef gate); 245 void LowerSuperCallArrow(GateRef gate); 246 void LowerSuperCallSpread(GateRef gate); 247 GateRef IsSuperFuncValid(GateRef superFunc); 248 GateRef IsAotOrFastCall(GateRef func, CircuitBuilder::JudgeMethodType type); 249 void LowerFastSuperCall(const std::vector<GateRef> &args, Variable *result, Label *exit, GateRef actualArgc, 250 bool isSuperCallSpread); 251 GateRef GetSuperCallArgs(const std::vector<GateRef> &args, bool isSuperCallSpread); 252 void LowerIsTrueOrFalse(GateRef gate, bool flag); 253 void LowerNewObjRange(GateRef gate); 254 bool IsDependIfStateMent(GateRef gate, size_t idx); 255 void LowerConditionJump(GateRef gate, bool isEqualJump); 256 void LowerGetNextPropName(GateRef gate); 257 void LowerCopyDataProperties(GateRef gate); 258 void LowerCreateObjectWithExcludedKeys(GateRef gate); 259 void LowerCreateRegExpWithLiteral(GateRef gate); 260 void LowerStOwnByValue(GateRef gate); 261 void LowerStOwnByIndex(GateRef gate); 262 void LowerStOwnByName(GateRef gate); 263 void LowerDefineFunc(GateRef gate); 264 void LowerNewLexicalEnv(GateRef gate); 265 void LowerNewLexicalEnvWithName(GateRef gate); 266 void LowerNewSendableEnv(GateRef gate); 267 void LowerPopLexicalEnv(GateRef gate); 268 void LowerLdSuperByValue(GateRef gate); 269 void LowerStSuperByValue(GateRef gate); 270 void LowerTryStGlobalByName(GateRef gate); 271 void LowerStConstToGlobalRecord(GateRef gate, bool isConst); 272 void LowerStOwnByValueWithNameSet(GateRef gate); 273 void LowerStOwnByNameWithNameSet(GateRef gate); 274 void LowerLdGlobalVar(GateRef gate); 275 void LowerLdObjByName(GateRef gate); 276 void LowerStObjByName(GateRef gate, bool isThis); 277 void LowerLdSuperByName(GateRef gate); 278 void LowerStSuperByName(GateRef gate); 279 void LowerDefineGetterSetterByValue(GateRef gate); 280 void LowerLdObjByIndex(GateRef gate); 281 void LowerStObjByIndex(GateRef gate); 282 void LowerLdObjByValue(GateRef gate, bool isThis); 283 void LowerStObjByValue(GateRef gate, bool isThis); 284 void LowerCreateGeneratorObj(GateRef gate); 285 void LowerStArraySpread(GateRef gate); 286 void LowerLdLexVar(GateRef gate); 287 void LowerLdSendableVar(GateRef gate); 288 void LowerStLexVar(GateRef gate); 289 void LowerStSendableVar(GateRef gate); 290 void LowerDefineClassWithBuffer(GateRef gate); 291 void LowerAsyncFunctionEnter(GateRef gate); 292 void LowerTypeof(GateRef gate); 293 void LowerResumeGenerator(GateRef gate); 294 void LowerStoreRegister(GateRef gate, GateRef arrayGate); 295 void LowerGetResumeMode(GateRef gate); 296 void LowerDefineMethod(GateRef gate); 297 void LowerGetUnmappedArgs(GateRef gate); 298 void LowerCopyRestArgs(GateRef gate); 299 void LowerCallStubWithIC(GateRef gate, int sign, const std::vector<GateRef> &args); 300 GateRef LowerCallRuntime(GateRef gate, int index, const std::vector<GateRef> &args, bool useLabel = false); 301 GateRef LowerCallNGCRuntime(GateRef gate, int index, const std::vector<GateRef> &args, bool useLabel = false); 302 void LowerCreateAsyncGeneratorObj(GateRef gate); 303 void LowerAsyncGeneratorResolve(GateRef gate); 304 void LowerAsyncGeneratorReject(GateRef gate); 305 void LowerSetGeneratorState(GateRef gate); 306 GateRef GetValueFromTaggedArray(GateRef arrayGate, GateRef indexOffset); 307 GateRef GetTaggedArrayFromValueIn(Environment *env, GateRef gate, size_t length); 308 GateRef LowerUpdateArrayHClassAtDefine(GateRef gate, GateRef array); 309 void AddProfiling(GateRef gate, bool skipGenerator = true); 310 GateRef FastStrictEqual(GateRef left, GateRef right); 311 void LowerWideLdPatchVar(GateRef gate); 312 void LowerWideStPatchVar(GateRef gate); 313 void LowerLdThisByName(GateRef gate); 314 bool IsFastCallArgs(size_t index); 315 void LowerConstruct(GateRef gate); 316 void LowerCallInternal(GateRef gate); 317 void LowerCallNew(GateRef gate); 318 void LowerTypedCall(GateRef gate); 319 void LowerTypedFastCall(GateRef gate); 320 void LowerCheckSafePointAndStackOver(GateRef gate); 321 void LowerLdPrivateProperty(GateRef gate); 322 void LowerStPrivateProperty(GateRef gate); 323 void LowerTestIn(GateRef gate); 324 void LowerNotifyConcurrentResult(GateRef gate); 325 void LowerDefineFieldByName(GateRef gate); 326 void LowerDefineFieldByValue(GateRef gate); 327 void LowerDefineFieldByIndex(GateRef gate); 328 void LowerToPropertyKey(GateRef gate); 329 void LowerCreatePrivateProperty(GateRef gate); 330 void LowerDefinePrivateProperty(GateRef gate); 331 void LowerCallInit(GateRef gate); 332 void LowerDefineSendableClass(GateRef gate); 333 void LowerLdSendableClass(GateRef gate); 334 void LowerGetEnv(GateRef gate); 335 void DeleteLoopExit(GateRef gate); 336 void DeleteLoopExitValue(GateRef gate); 337 void LowerLdStr(GateRef gate); 338 void LowerGetSharedConstPool(GateRef gate); 339 void LowerGetUnsharedConstPool(GateRef gate); 340 void LowerLdLazyExternalModuleVar(GateRef gate); 341 void LowerLdLazySendableExternalModuleVar(GateRef gate); 342 343 CompilationEnv *compilationEnv_; 344 const MethodLiteral *methodLiteral_ {nullptr}; 345 Circuit *circuit_; 346 GateAccessor acc_; 347 ArgumentAccessor argAcc_; 348 CircuitBuilder builder_; 349 bool enableLog_ {false}; 350 bool traceBc_ {false}; 351 bool profiling_ {false}; 352 bool stressDeopt_ {false}; 353 std::string methodName_; 354 GateRef glue_ {Circuit::NullGate()}; 355 CVector<GateRef> unsharedCP_; 356 }; 357 } // panda::ecmascript::kungfu 358 #endif // ECMASCRIPT_COMPILER_SLOWPATH_LOWERING_H 359