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, ¬X);
82 Bind(&isX);
83 {
84 result = y;
85 Jump(&exit);
86 }
87 Bind(¬X);
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, ¬X);
106 Bind(&isX);
107 {
108 Jump(&exit);
109 }
110 Bind(¬X);
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