• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_TYPE_MCR_LOWERING_H
17 #define ECMASCRIPT_COMPILER_TYPE_MCR_LOWERING_H
18 
19 #include "ecmascript/compiler/argument_accessor.h"
20 #include "ecmascript/compiler/bytecode_circuit_builder.h"
21 #include "ecmascript/compiler/circuit_builder-inl.h"
22 
23 namespace panda::ecmascript::kungfu {
24 // TypeMCRLowering Process
25 // SW: state wire, DW: depend wire, VW: value wire
26 // Before Type Lowering:
27 //                                    SW   DW   VW
28 //                                    |    |    |
29 //                                    |    |    |
30 //                                    v    v    v
31 //                                +-------------------+
32 //                                |       (HIR)       |    SW     +--------------+
33 //                            --DW|    JS_BYTECODE    |---------->| IF_EXCEPTION |
34 //                            |   +-------------------+           +--------------+
35 //                            |            SW       VW
36 //                            |            |        |
37 //                            |            v        |
38 //                            |    +--------------+ |
39 //                            |    |  IF_SUCCESS  | |
40 //                            |    +--------------+ |
41 //                            |            SW       |
42 //                            |            |        |
43 //                            |            v        v
44 //                            |   +-------------------+
45 //                            |   |       (HIR)       |
46 //                            --->|    JS_BYTECODE    |
47 //                                +-------------------+
48 //
49 // After Type Lowering:
50 //                                           SW
51 //                                           |
52 //                                           v
53 //                                 +-------------------+
54 //                                 |     IF_BRANCH     |
55 //                                 |    (Type Check)   |
56 //                                 +-------------------+
57 //                                    SW            SW
58 //                                    |             |
59 //                                    V             V
60 //                            +--------------+  +--------------+
61 //                            |    IF_TRUE   |  |   IF_FALSE   |
62 //                            +--------------+  +--------------+
63 //                 VW   DW          SW               SW                   DW   VW
64 //                 |    |           |                |                    |    |
65 //                 |    |           V                V                    |    |
66 //                 |    |  +---------------+     +---------------------+  |    |
67 //                 ------->|   FAST PATH   |     |        (HIR)        |<-------
68 //                         +---------------+     |     JS_BYTECODE     |
69 //                            VW  DW   SW        +---------------------+
70 //                            |   |    |               SW         VW  DW
71 //                            |   |    |               |          |   |
72 //                            |   |    |               v          |   |
73 //                            |   |    |         +--------------+ |   |
74 //                            |   |    |         |  IF_SUCCESS  | |   |
75 //                            |   |    |         +--------------+ |   |
76 //                            |   |    |                SW        |   |
77 //                            |   |    |                |         |   |
78 //                            |   |    v                v         |   |
79 //                            |   |  +---------------------+      |   |
80 //                            |   |  |        MERGE        |      |   |
81 //                            |   |  +---------------------+      |   |
82 //                            |   |    SW         SW    SW        |   |
83 //                            ----|----|----------|-----|--       |   |
84 //                             ---|----|----------|-----|-|-------|----
85 //                             |  |    |          |     | |       |
86 //                             v  v    v          |     v v       v
87 //                            +-----------------+ | +----------------+
88 //                            | DEPEND_SELECTOR | | | VALUE_SELECTOR |
89 //                            +-----------------+ | +----------------+
90 //                                    DW          |        VW
91 //                                    |           |        |
92 //                                    v           v        v
93 //                                  +------------------------+
94 //                                  |         (HIR)          |
95 //                                  |      JS_BYTECODE       |
96 //                                  +------------------------+
97 
98 class TypeMCRLowering {
99 public:
TypeMCRLowering(Circuit * circuit,CompilationConfig * cmpCfg,TSManager * tsManager,bool enableLog,const std::string & name)100     TypeMCRLowering(Circuit *circuit, CompilationConfig *cmpCfg, TSManager *tsManager,
101                  bool enableLog, const std::string& name)
102         : circuit_(circuit), acc_(circuit), builder_(circuit, cmpCfg),
103           dependEntry_(circuit->GetDependRoot()), tsManager_(tsManager),
104           enableLog_(enableLog), methodName_(name) {}
105 
106     ~TypeMCRLowering() = default;
107 
108     void RunTypeMCRLowering();
109 
110 private:
IsLogEnabled()111     bool IsLogEnabled() const
112     {
113         return enableLog_;
114     }
115 
GetMethodName()116     const std::string& GetMethodName() const
117     {
118         return methodName_;
119     }
120 
121     void Lower(GateRef gate);
122     void LowerType(GateRef gate);
123     void LowerPrimitiveTypeCheck(GateRef gate);
124     void LowerTypeConvert(GateRef gate);
125     void LowerPrimitiveToNumber(GateRef dst, GateRef src, GateType srcType);
126     void LowerIntCheck(GateRef gate);
127     void LowerDoubleCheck(GateRef gate);
128     void LowerNumberCheck(GateRef gate);
129     void LowerBooleanCheck(GateRef gate);
130     void LowerIndexCheck(GateRef gate);
131     void LowerObjectTypeCheck(GateRef gate);
132     void LowerSimpleHClassCheck(GateRef gate);
133     void LowerTSSubtypingCheck(GateRef gate);
134     void LowerObjectTypeCompare(GateRef gate);
135     void LowerSimpleHClassCompare(GateRef gate);
136     void LowerTSSubtypingCompare(GateRef gate);
137     GateRef BuildCompareSubTyping(GateRef gate, GateRef frameState, Label *levelValid, Label *exit);
138     GateRef BuildCompareHClass(GateRef gate, GateRef frameState);
139     void BuildCompareSubTyping(GateRef gate);
140     void LowerStableArrayCheck(GateRef gate);
141     void LowerTypedArrayCheck(GateRef gate);
142     void LowerLoadTypedArrayLength(GateRef gate);
143     void LowerLoadProperty(GateRef gate);
144     void LowerCallGetter(GateRef gate, GateRef glue);
145     void LowerStoreProperty(GateRef gate);
146     void LowerCallSetter(GateRef gate, GateRef glue);
147     void LowerLoadArrayLength(GateRef gate);
148     void LowerStoreElement(GateRef gate, GateRef glue);
149     void LowerLoadElement(GateRef gate);
150     void LowerLoadFromTaggedArray(GateRef gate);
151     void LowerStoreToTaggedArray(GateRef gate, GateRef glue);
152 
153     enum class ArrayState : uint8_t {
154         PACKED = 0,
155         HOLEY,
156     };
157     void LowerArrayLoadElement(GateRef gate, ArrayState arrayState);
158     void LowerCowArrayCheck(GateRef gate, GateRef glue);
159     void LowerTypedArrayLoadElement(GateRef gate, BuiltinTypeId id);
160     void LowerArrayStoreElement(GateRef gate, GateRef glue);
161     void LowerTypedArrayStoreElement(GateRef gate, BuiltinTypeId id);
162     void LowerUInt8ClampedArrayStoreElement(GateRef gate);
163     void LowerTypedCallBuitin(GateRef gate);
164     void LowerCallTargetCheck(GateRef gate);
165     void LowerJSCallTargetCheck(GateRef gate);
166     void LowerJSCallTargetFromDefineFuncCheck(GateRef gate);
167     void LowerJSCallTargetTypeCheck(GateRef gate);
168     void LowerJSFastCallTargetTypeCheck(GateRef gate);
169     void LowerJSCallThisTargetTypeCheck(GateRef gate);
170     void LowerJSFastCallThisTargetTypeCheck(GateRef gate);
171     void LowerJSNoGCCallThisTargetTypeCheck(GateRef gate);
172     void LowerJSNoGCFastCallThisTargetTypeCheck(GateRef gate);
173     void LowerTypedNewAllocateThis(GateRef gate, GateRef glue);
174     void LowerTypedSuperAllocateThis(GateRef gate, GateRef glue);
175     void LowerGetSuperConstructor(GateRef gate);
176     void LowerJSInlineTargetTypeCheck(GateRef gate);
177     void SetDeoptTypeInfo(BuiltinTypeId id, DeoptType &type, size_t &funcIndex);
178     void LowerLoadGetter(GateRef gate);
179     void LowerLoadSetter(GateRef gate);
180     void LowerInlineAccessorCheck(GateRef gate);
181 
182     GateRef LowerCallRuntime(GateRef glue, GateRef hirGate, int index, const std::vector<GateRef> &args,
183                              bool useLabel = false);
184 
185     enum AccessorMode {
186         GETTER,
187         SETTER,
188     };
189 
190     GateRef CallAccessor(GateRef glue, GateRef gate, GateRef function, GateRef receiver, AccessorMode mode,
191                          GateRef value = Circuit::NullGate());
192     void ReplaceHirWithPendingException(GateRef hirGate, GateRef glue, GateRef state, GateRef depend, GateRef value);
193 
194     GateRef DoubleToTaggedDoublePtr(GateRef gate);
195     GateRef ChangeInt32ToFloat64(GateRef gate);
196     GateRef TruncDoubleToInt(GateRef gate);
197     GateRef IntToTaggedIntPtr(GateRef x);
198     GateType GetLeftType(GateRef gate);
199     GateType GetRightType(GateRef gate);
200     GateRef GetObjectFromConstPool(GateRef jsFunc, GateRef index);
201     GateRef GetElementSize(BuiltinTypeId id);
202     VariableType GetVariableType(BuiltinTypeId id);
203 
GetFrameState(GateRef gate)204     GateRef GetFrameState(GateRef gate) const
205     {
206         return acc_.GetFrameState(gate);
207     }
208 
209     VariableType GetVarType(PropertyLookupResult plr);
210     GateRef LoadSupers(GateRef hclass);
211     GateRef GetLengthFromSupers(GateRef supers);
212     GateRef GetValueFromSupers(GateRef supers, size_t index);
213     GateRef LoadFromTaggedArray(GateRef array, size_t index);
214     GateRef LoadFromConstPool(GateRef jsFunc, size_t index);
215     GateRef LoadFromVTable(GateRef receiver, size_t index);
216 
217     Circuit *circuit_;
218     GateAccessor acc_;
219     CircuitBuilder builder_;
220     GateRef dependEntry_;
221     [[maybe_unused]] TSManager *tsManager_ {nullptr};
222     bool enableLog_ {false};
223     std::string methodName_;
224 };
225 }  // panda::ecmascript::kungfu
226 #endif  // ECMASCRIPT_COMPILER_TYPE_MCR_LOWERING_H
227