• 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 #ifndef ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_INL_H
16 #define ECMASCRIPT_COMPILER_CIRCUIT_BUILDER_INL_H
17 
18 #include "ecmascript/compiler/lcr_circuit_builder.h"
19 #include "ecmascript/compiler/mcr_circuit_builder.h"
20 #include "ecmascript/compiler/hcr_circuit_builder.h"
21 #include "ecmascript/compiler/circuit_builder.h"
22 #include "ecmascript/mem/region.h"
23 #include "ecmascript/method.h"
24 
25 namespace panda::ecmascript::kungfu {
26 // constant
True()27 GateRef CircuitBuilder::True()
28 {
29     return Boolean(true);
30 }
31 
False()32 GateRef CircuitBuilder::False()
33 {
34     return Boolean(false);
35 }
36 
Undefined()37 GateRef CircuitBuilder::Undefined()
38 {
39     return UndefineConstant();
40 }
41 
Hole()42 GateRef CircuitBuilder::Hole()
43 {
44     return HoleConstant();
45 }
46 
DoubleIsINF(GateRef x)47 GateRef CircuitBuilder::DoubleIsINF(GateRef x)
48 {
49     GateRef infinity = Double(base::POSITIVE_INFINITY);
50     GateRef negativeInfinity = Double(-base::POSITIVE_INFINITY);
51     GateRef diff1 = DoubleEqual(x, infinity);
52     GateRef diff2 = DoubleEqual(x, negativeInfinity);
53     return BoolOr(diff1, diff2);
54 }
55 
56 // Js World
57 // cast operation
58 
GetGlobalConstantOffset(ConstantIndex index)59 GateRef CircuitBuilder::GetGlobalConstantOffset(ConstantIndex index)
60 {
61     return PtrMul(IntPtr(sizeof(JSTaggedValue)), IntPtr(static_cast<int>(index)));
62 }
63 
GetExpectedNumOfArgs(GateRef method)64 GateRef CircuitBuilder::GetExpectedNumOfArgs(GateRef method)
65 {
66     GateRef callFieldOffset = IntPtr(Method::CALL_FIELD_OFFSET);
67     GateRef callfield = Load(VariableType::INT64(), method, callFieldOffset);
68     return Int64And(
69         Int64LSR(callfield, Int64(MethodLiteral::NumArgsBits::START_BIT)),
70         Int64((1LU << MethodLiteral::NumArgsBits::SIZE) - 1));
71 }
72 
LogicAnd(GateRef x,GateRef y)73 GateRef CircuitBuilder::LogicAnd(GateRef x, GateRef y)
74 {
75     Label subentry(env_);
76     SubCfgEntry(&subentry);
77     Label exit(env_);
78     Label isX(env_);
79     Label notX(env_);
80     DEFVALUE(result, env_, VariableType::BOOL(), x);
81     Branch(x, &isX, &notX);
82     Bind(&isX);
83     {
84         result = y;
85         Jump(&exit);
86     }
87     Bind(&notX);
88     {
89         Jump(&exit);
90     }
91     Bind(&exit);
92     auto ret = *result;
93     SubCfgExit();
94     return ret;
95 }
96 
LogicOr(GateRef x,GateRef y)97 GateRef CircuitBuilder::LogicOr(GateRef x, GateRef y)
98 {
99     Label subentry(env_);
100     SubCfgEntry(&subentry);
101     Label exit(env_);
102     Label isX(env_);
103     Label notX(env_);
104     DEFVALUE(result, env_, VariableType::BOOL(), x);
105     Branch(x, &isX, &notX);
106     Bind(&isX);
107     {
108         Jump(&exit);
109     }
110     Bind(&notX);
111     {
112         result = y;
113         Jump(&exit);
114     }
115     Bind(&exit);
116     auto ret = *result;
117     SubCfgExit();
118     return ret;
119 }
120 
NextVariableId()121 int CircuitBuilder::NextVariableId()
122 {
123     return env_->NextVariableId();
124 }
125 
HandleException(GateRef result,Label * success,Label * fail,Label * exit)126 void CircuitBuilder::HandleException(GateRef result, Label *success, Label *fail, Label *exit)
127 {
128     Branch(Equal(result, ExceptionConstant()), fail, success);
129     Bind(fail);
130     {
131         Jump(exit);
132     }
133 }
134 
HandleException(GateRef result,Label * success,Label * fail,Label * exit,GateRef exceptionVal)135 void CircuitBuilder::HandleException(GateRef result, Label *success, Label *fail, Label *exit, GateRef exceptionVal)
136 {
137     Branch(Equal(result, exceptionVal), fail, success);
138     Bind(fail);
139     {
140         Jump(exit);
141     }
142 }
143 
SubCfgEntry(Label * entry)144 void CircuitBuilder::SubCfgEntry(Label *entry)
145 {
146     ASSERT(env_ != nullptr);
147     env_->SubCfgEntry(entry);
148 }
149 
SubCfgExit()150 void CircuitBuilder::SubCfgExit()
151 {
152     ASSERT(env_ != nullptr);
153     env_->SubCfgExit();
154 }
155 
Return(GateRef value)156 GateRef CircuitBuilder::Return(GateRef value)
157 {
158     auto control = GetCurrentLabel()->GetControl();
159     auto depend = GetCurrentLabel()->GetDepend();
160     return Return(control, depend, value);
161 }
162 
Return()163 GateRef CircuitBuilder::Return()
164 {
165     auto control = GetCurrentLabel()->GetControl();
166     auto depend = GetCurrentLabel()->GetDepend();
167     return ReturnVoid(control, depend);
168 }
169 
Bind(Label * label)170 void CircuitBuilder::Bind(Label *label)
171 {
172     label->Bind();
173     env_->SetCurrentLabel(label);
174 }
175 
Bind(Label * label,bool justSlowPath)176 void CircuitBuilder::Bind(Label *label, bool justSlowPath)
177 {
178     if (!justSlowPath) {
179         label->Bind();
180         env_->SetCurrentLabel(label);
181     }
182 }
183 
GetState()184 GateRef CircuitBuilder::GetState() const
185 {
186     return GetCurrentLabel()->GetControl();
187 }
188 
GetDepend()189 GateRef CircuitBuilder::GetDepend() const
190 {
191     return GetCurrentLabel()->GetDepend();
192 }
193 
GetStateDepend()194 StateDepend CircuitBuilder::GetStateDepend() const
195 {
196     return StateDepend(GetState(), GetDepend());
197 }
198 
SetDepend(GateRef depend)199 void CircuitBuilder::SetDepend(GateRef depend)
200 {
201     GetCurrentLabel()->SetDepend(depend);
202 }
203 
SetState(GateRef state)204 void CircuitBuilder::SetState(GateRef state)
205 {
206     GetCurrentLabel()->SetControl(state);
207 }
208 
GetCurrentLabel()209 Label *CircuitBuilder::GetCurrentLabel() const
210 {
211     return GetCurrentEnvironment()->GetCurrentLabel();
212 }
213 } // namespace panda::ecmascript::kungfu
214 
215 #endif
216