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