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 
27 namespace 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 
112 class SlowPathLowering {
113 public:
SlowPathLowering(Circuit *circuit, CompilationConfig *cmpCfg, PassContext *ctx, const MethodLiteral *methodLiteral, bool enableLog, const std::string& name)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 
IsLogEnabled() const129     bool IsLogEnabled() const
130     {
131         return enableLog_;
132     }
133 
IsTraceBC() const134     bool IsTraceBC() const
135     {
136         return traceBc_;
137     }
138 
IsProfiling() const139     bool IsProfiling() const
140     {
141         return profiling_;
142     }
143 
IsStressDeopt() const144     bool IsStressDeopt() const
145     {
146         return stressDeopt_;
147     }
148 
149 private:
GetMethodName() const150     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