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