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 #include "ecmascript/compiler/argument_accessor.h"
17 #include "ecmascript/compiler/circuit_builder.h"
18 #include "ecmascript/compiler/gate_accessor.h"
19
20 namespace panda::ecmascript::kungfu {
21 using UseIterator = GateAccessor::UseIterator;
22
GetNumIns(GateRef gate) const23 size_t GateAccessor::GetNumIns(GateRef gate) const
24 {
25 Gate *gatePtr = circuit_->LoadGatePtr(gate);
26 return gatePtr->GetNumIns();
27 }
28
GetMark(GateRef gate) const29 MarkCode GateAccessor::GetMark(GateRef gate) const
30 {
31 return circuit_->GetMark(gate);
32 }
33
SetMark(GateRef gate,MarkCode mark)34 void GateAccessor::SetMark(GateRef gate, MarkCode mark)
35 {
36 circuit_->SetMark(gate, mark);
37 }
38
IsFinished(GateRef gate) const39 bool GateAccessor::IsFinished(GateRef gate) const
40 {
41 return GetMark(gate) == MarkCode::FINISHED;
42 }
43
IsVisited(GateRef gate) const44 bool GateAccessor::IsVisited(GateRef gate) const
45 {
46 return GetMark(gate) == MarkCode::VISITED;
47 }
48
IsNotMarked(GateRef gate) const49 bool GateAccessor::IsNotMarked(GateRef gate) const
50 {
51 return GetMark(gate) == MarkCode::NO_MARK;
52 }
53
SetFinished(GateRef gate)54 void GateAccessor::SetFinished(GateRef gate)
55 {
56 SetMark(gate, MarkCode::FINISHED);
57 }
58
SetVisited(GateRef gate)59 void GateAccessor::SetVisited(GateRef gate)
60 {
61 SetMark(gate, MarkCode::VISITED);
62 }
63
GetOpCode(GateRef gate) const64 OpCode GateAccessor::GetOpCode(GateRef gate) const
65 {
66 Gate *gatePtr = circuit_->LoadGatePtr(gate);
67 return gatePtr->GetOpCode();
68 }
69
TryGetValue(GateRef gate) const70 BitField GateAccessor::TryGetValue(GateRef gate) const
71 {
72 Gate *gatePtr = circuit_->LoadGatePtr(gate);
73 return gatePtr->TryGetValue();
74 }
75
GetICmpCondition(GateRef gate) const76 ICmpCondition GateAccessor::GetICmpCondition(GateRef gate) const
77 {
78 ASSERT(GetOpCode(gate) == OpCode::ICMP);
79 Gate *gatePtr = circuit_->LoadGatePtr(gate);
80 return static_cast<ICmpCondition>(gatePtr->GetOneParameterMetaData()->GetValue());
81 }
82
GetFCmpCondition(GateRef gate) const83 FCmpCondition GateAccessor::GetFCmpCondition(GateRef gate) const
84 {
85 ASSERT(GetOpCode(gate) == OpCode::FCMP);
86 Gate *gatePtr = circuit_->LoadGatePtr(gate);
87 return static_cast<FCmpCondition>(gatePtr->GetOneParameterMetaData()->GetValue());
88 }
89
GetConstDataId(GateRef gate) const90 ConstDataId GateAccessor::GetConstDataId(GateRef gate) const
91 {
92 ASSERT(GetOpCode(gate) == OpCode::CONST_DATA);
93 Gate *gatePtr = circuit_->LoadGatePtr(gate);
94 return ConstDataId(gatePtr->GetOneParameterMetaData()->GetValue());
95 }
96
GetTypedUnOp(GateRef gate) const97 TypedUnaryAccessor GateAccessor::GetTypedUnOp(GateRef gate) const
98 {
99 ASSERT(GetOpCode(gate) == OpCode::TYPED_UNARY_OP);
100 Gate *gatePtr = circuit_->LoadGatePtr(gate);
101 return TypedUnaryAccessor(gatePtr->GetOneParameterMetaData()->GetValue());
102 }
103
GetTypedLoadOp(GateRef gate) const104 TypedLoadOp GateAccessor::GetTypedLoadOp(GateRef gate) const
105 {
106 ASSERT(GetOpCode(gate) == OpCode::LOAD_ELEMENT);
107 Gate *gatePtr = circuit_->LoadGatePtr(gate);
108 return static_cast<TypedLoadOp>(gatePtr->GetOneParameterMetaData()->GetValue());
109 }
110
GetTypedStoreOp(GateRef gate) const111 TypedStoreOp GateAccessor::GetTypedStoreOp(GateRef gate) const
112 {
113 ASSERT(GetOpCode(gate) == OpCode::STORE_ELEMENT);
114 Gate *gatePtr = circuit_->LoadGatePtr(gate);
115 return static_cast<TypedStoreOp>(gatePtr->GetOneParameterMetaData()->GetValue());
116 }
117
GetTypedBinaryOp(GateRef gate) const118 TypedBinOp GateAccessor::GetTypedBinaryOp(GateRef gate) const
119 {
120 ASSERT(GetOpCode(gate) == OpCode::TYPED_BINARY_OP);
121 Gate *gatePtr = circuit_->LoadGatePtr(gate);
122 return gatePtr->GetTypedBinaryMegaData()->GetTypedBinaryOp();
123 }
124
GetParamGateType(GateRef gate) const125 GateType GateAccessor::GetParamGateType(GateRef gate) const
126 {
127 ASSERT(GetOpCode(gate) == OpCode::PRIMITIVE_TYPE_CHECK ||
128 GetOpCode(gate) == OpCode::OBJECT_TYPE_CHECK ||
129 GetOpCode(gate) == OpCode::ARRAY_CHECK ||
130 GetOpCode(gate) == OpCode::STABLE_ARRAY_CHECK ||
131 GetOpCode(gate) == OpCode::TYPED_ARRAY_CHECK ||
132 GetOpCode(gate) == OpCode::INDEX_CHECK);
133 Gate *gatePtr = circuit_->LoadGatePtr(gate);
134 GateTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
135 return accessor.GetGateType();
136 }
137
GetLeftType(GateRef gate) const138 GateType GateAccessor::GetLeftType(GateRef gate) const
139 {
140 ASSERT(GetOpCode(gate) == OpCode::TYPED_UNARY_OP ||
141 GetOpCode(gate) == OpCode::TYPED_BINARY_OP ||
142 GetOpCode(gate) == OpCode::TYPE_CONVERT);
143 Gate *gatePtr = circuit_->LoadGatePtr(gate);
144 GatePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
145 return accessor.GetLeftType();
146 }
147
GetRightType(GateRef gate) const148 GateType GateAccessor::GetRightType(GateRef gate) const
149 {
150 ASSERT(GetOpCode(gate) == OpCode::TYPED_BINARY_OP ||
151 GetOpCode(gate) == OpCode::TYPE_CONVERT);
152 Gate *gatePtr = circuit_->LoadGatePtr(gate);
153 GatePairTypeAccessor accessor(gatePtr->GetOneParameterMetaData()->GetValue());
154 return accessor.GetRightType();
155 }
156
GetVirtualRegisterIndex(GateRef gate) const157 size_t GateAccessor::GetVirtualRegisterIndex(GateRef gate) const
158 {
159 ASSERT(GetOpCode(gate) == OpCode::SAVE_REGISTER ||
160 GetOpCode(gate) == OpCode::RESTORE_REGISTER);
161 Gate *gatePtr = circuit_->LoadGatePtr(gate);
162 return static_cast<size_t>(gatePtr->GetOneParameterMetaData()->GetValue());
163 }
164
GetConstantValue(GateRef gate) const165 uint64_t GateAccessor::GetConstantValue(GateRef gate) const
166 {
167 ASSERT(GetOpCode(gate) == OpCode::CONSTANT);
168 Gate *gatePtr = circuit_->LoadGatePtr(gate);
169 return gatePtr->GetOneParameterMetaData()->GetValue();
170 }
171
GetBytecodeIndex(GateRef gate) const172 uint32_t GateAccessor::GetBytecodeIndex(GateRef gate) const
173 {
174 ASSERT(GetOpCode(gate) == OpCode::JS_BYTECODE);
175 Gate *gatePtr = circuit_->LoadGatePtr(gate);
176 return gatePtr->GetJSBytecodeMetaData()->GetBytecodeIndex();
177 }
178
GetByteCodeOpcode(GateRef gate) const179 EcmaOpcode GateAccessor::GetByteCodeOpcode(GateRef gate) const
180 {
181 ASSERT(GetOpCode(gate) == OpCode::JS_BYTECODE);
182 Gate *gatePtr = circuit_->LoadGatePtr(gate);
183 return gatePtr->GetJSBytecodeMetaData()->GetByteCodeOpcode();
184 }
185
Print(GateRef gate) const186 void GateAccessor::Print(GateRef gate) const
187 {
188 Gate *gatePtr = circuit_->LoadGatePtr(gate);
189 gatePtr->Print();
190 }
191
ShortPrint(GateRef gate) const192 void GateAccessor::ShortPrint(GateRef gate) const
193 {
194 Gate *gatePtr = circuit_->LoadGatePtr(gate);
195 gatePtr->ShortPrint();
196 }
197
GetId(GateRef gate) const198 GateId GateAccessor::GetId(GateRef gate) const
199 {
200 Gate *gatePtr = circuit_->LoadGatePtr(gate);
201 return gatePtr->GetId();
202 }
203
GetInValueStarts(GateRef gate) const204 size_t GateAccessor::GetInValueStarts(GateRef gate) const
205 {
206 Gate *gatePtr = circuit_->LoadGatePtr(gate);
207 return gatePtr->GetInValueStarts();
208 }
209
GetValueIn(GateRef gate,size_t idx) const210 GateRef GateAccessor::GetValueIn(GateRef gate, size_t idx) const
211 {
212 Gate *gatePtr = circuit_->LoadGatePtr(gate);
213 ASSERT(idx < gatePtr->GetInValueCount());
214 size_t valueIndex = gatePtr->GetInValueStarts();
215 return circuit_->GetIn(gate, valueIndex + idx);
216 }
217
GetNumValueIn(GateRef gate) const218 size_t GateAccessor::GetNumValueIn(GateRef gate) const
219 {
220 Gate *gatePtr = circuit_->LoadGatePtr(gate);
221 return gatePtr->GetInValueCount();
222 }
223
IsGCRelated(GateRef gate) const224 bool GateAccessor::IsGCRelated(GateRef gate) const
225 {
226 return GetGateType(gate).IsGCRelated();
227 }
228
GetIn(GateRef gate,size_t idx) const229 GateRef GateAccessor::GetIn(GateRef gate, size_t idx) const
230 {
231 return circuit_->GetIn(gate, idx);
232 }
233
GetState(GateRef gate,size_t idx) const234 GateRef GateAccessor::GetState(GateRef gate, size_t idx) const
235 {
236 ASSERT(idx < circuit_->LoadGatePtr(gate)->GetStateCount());
237 return circuit_->GetIn(gate, idx);
238 }
239
GetInStates(GateRef gate,std::vector<GateRef> & ins) const240 void GateAccessor::GetInStates(GateRef gate, std::vector<GateRef>& ins) const
241 {
242 const Gate *curGate = circuit_->LoadGatePtrConst(gate);
243 for (size_t idx = 0; idx < curGate->GetStateCount(); idx++) {
244 ins.push_back(circuit_->GetGateRef(curGate->GetInGateConst(idx)));
245 }
246 }
247
GetIns(GateRef gate,std::vector<GateRef> & ins) const248 void GateAccessor::GetIns(GateRef gate, std::vector<GateRef>& ins) const
249 {
250 const Gate *curGate = circuit_->LoadGatePtrConst(gate);
251 for (size_t idx = 0; idx < curGate->GetNumIns(); idx++) {
252 ins.push_back(circuit_->GetGateRef(curGate->GetInGateConst(idx)));
253 }
254 }
255
GetOuts(GateRef gate,std::vector<GateRef> & outs) const256 void GateAccessor::GetOuts(GateRef gate, std::vector<GateRef>& outs) const
257 {
258 const Gate *curGate = circuit_->LoadGatePtrConst(gate);
259 if (!curGate->IsFirstOutNull()) {
260 const Out *curOut = curGate->GetFirstOutConst();
261 GateRef ref = circuit_->GetGateRef(curOut->GetGateConst());
262 outs.push_back(ref);
263 while (!curOut->IsNextOutNull()) {
264 curOut = curOut->GetNextOutConst();
265 ref = circuit_->GetGateRef(curOut->GetGateConst());
266 outs.push_back(ref);
267 }
268 }
269 }
270
GetOutStates(GateRef gate,std::vector<GateRef> & outStates) const271 void GateAccessor::GetOutStates(GateRef gate, std::vector<GateRef>& outStates) const
272 {
273 const Gate *curGate = circuit_->LoadGatePtrConst(gate);
274 if (!curGate->IsFirstOutNull()) {
275 const Out *curOut = curGate->GetFirstOutConst();
276 GateRef ref = circuit_->GetGateRef(curOut->GetGateConst());
277 if (GetMetaData(ref)->IsState()) {
278 outStates.push_back(ref);
279 }
280 while (!curOut->IsNextOutNull()) {
281 curOut = curOut->GetNextOutConst();
282 ref = circuit_->GetGateRef(curOut->GetGateConst());
283 if (GetMetaData(ref)->IsState()) {
284 outStates.push_back(ref);
285 }
286 }
287 }
288 }
289
GetStateUses(GateRef gate,std::vector<GateRef> & stateUses)290 void GateAccessor::GetStateUses(GateRef gate, std::vector<GateRef>& stateUses)
291 {
292 stateUses.clear();
293 auto uses = Uses(gate);
294 for (auto it = uses.begin(); it != uses.end(); it++) {
295 if (IsStateIn(it)) {
296 stateUses.emplace_back(*it);
297 }
298 }
299 }
300
GetDependUses(GateRef gate,std::vector<GateRef> & dependUses)301 void GateAccessor::GetDependUses(GateRef gate, std::vector<GateRef>& dependUses)
302 {
303 dependUses.clear();
304 auto uses = Uses(gate);
305 for (auto it = uses.begin(); it != uses.end(); it++) {
306 if (IsDependIn(it)) {
307 dependUses.emplace_back(*it);
308 }
309 }
310 }
311
GetAllGates(std::vector<GateRef> & gates) const312 void GateAccessor::GetAllGates(std::vector<GateRef>& gates) const
313 {
314 circuit_->GetAllGates(gates);
315 }
316
IsInGateNull(GateRef gate,size_t idx) const317 bool GateAccessor::IsInGateNull(GateRef gate, size_t idx) const
318 {
319 return circuit_->IsInGateNull(gate, idx);
320 }
321
IsSelector(GateRef g) const322 bool GateAccessor::IsSelector(GateRef g) const
323 {
324 return GetOpCode(g) == OpCode::VALUE_SELECTOR;
325 }
326
IsControlCase(GateRef gate) const327 bool GateAccessor::IsControlCase(GateRef gate) const
328 {
329 return circuit_->IsControlCase(gate);
330 }
331
IsLoopHead(GateRef gate) const332 bool GateAccessor::IsLoopHead(GateRef gate) const
333 {
334 return circuit_->IsLoopHead(gate);
335 }
336
IsLoopBack(GateRef gate) const337 bool GateAccessor::IsLoopBack(GateRef gate) const
338 {
339 return GetOpCode(gate) == OpCode::LOOP_BACK;
340 }
341
IsState(GateRef gate) const342 bool GateAccessor::IsState(GateRef gate) const
343 {
344 return GetMetaData(gate)->IsState();
345 }
346
IsConstant(GateRef gate) const347 bool GateAccessor::IsConstant(GateRef gate) const
348 {
349 return GetMetaData(gate)->IsConstant();
350 }
351
IsDependSelector(GateRef gate) const352 bool GateAccessor::IsDependSelector(GateRef gate) const
353 {
354 return GetMetaData(gate)->IsDependSelector();
355 }
356
IsConstantValue(GateRef gate,uint64_t value) const357 bool GateAccessor::IsConstantValue(GateRef gate, uint64_t value) const
358 {
359 auto isConstant = IsConstant(gate);
360 if (isConstant) {
361 uint64_t bitField = GetConstantValue(gate);
362 return bitField == value;
363 }
364 return false;
365 }
366
IsTypedOperator(GateRef gate) const367 bool GateAccessor::IsTypedOperator(GateRef gate) const
368 {
369 return GetMetaData(gate)->IsTypedOperator();
370 }
371
IsNotWrite(GateRef gate) const372 bool GateAccessor::IsNotWrite(GateRef gate) const
373 {
374 return GetMetaData(gate)->IsNotWrite();
375 }
376
IsCheckWithTwoIns(GateRef gate) const377 bool GateAccessor::IsCheckWithTwoIns(GateRef gate) const
378 {
379 return GetMetaData(gate)->IsCheckWithTwoIns();
380 }
381
IsCheckWithOneIn(GateRef gate) const382 bool GateAccessor::IsCheckWithOneIn(GateRef gate) const
383 {
384 return GetMetaData(gate)->IsCheckWithOneIn();
385 }
386
IsSchedulable(GateRef gate) const387 bool GateAccessor::IsSchedulable(GateRef gate) const
388 {
389 return GetMetaData(gate)->IsSchedulable();
390 }
391
GetDep(GateRef gate,size_t idx) const392 GateRef GateAccessor::GetDep(GateRef gate, size_t idx) const
393 {
394 Gate *gatePtr = circuit_->LoadGatePtr(gate);
395 ASSERT(idx < gatePtr->GetDependCount());
396 size_t dependIndex = gatePtr->GetStateCount();
397 return circuit_->GetIn(gate, dependIndex + idx);
398 }
399
GetImmediateId(GateRef gate) const400 size_t GateAccessor::GetImmediateId(GateRef gate) const
401 {
402 Gate *gatePtr = circuit_->LoadGatePtr(gate);
403 ASSERT(gatePtr->GetGateType() == GateType::NJSValue());
404 ASSERT(gatePtr->GetOpCode() == OpCode::CONSTANT);
405 ASSERT(gatePtr->GetMachineType() == MachineType::I64);
406 size_t imm = gatePtr->GetOneParameterMetaData()->GetValue();
407 return imm;
408 }
409
SetDep(GateRef gate,GateRef depGate,size_t idx)410 void GateAccessor::SetDep(GateRef gate, GateRef depGate, size_t idx)
411 {
412 Gate *gatePtr = circuit_->LoadGatePtr(gate);
413 ASSERT(idx < gatePtr->GetDependCount());
414 size_t dependIndex = gatePtr->GetStateCount();
415 gatePtr->ModifyIn(dependIndex + idx, circuit_->LoadGatePtr(depGate));
416 }
417
ReplaceIn(const UseIterator & useIt,GateRef replaceGate)418 UseIterator GateAccessor::ReplaceIn(const UseIterator &useIt, GateRef replaceGate)
419 {
420 UseIterator next = useIt;
421 next++;
422 Gate *curGatePtr = circuit_->LoadGatePtr(*useIt);
423 Gate *replaceGatePtr = circuit_->LoadGatePtr(replaceGate);
424 curGatePtr->ModifyIn(useIt.GetIndex(), replaceGatePtr);
425 return next;
426 }
427
GetGateType(GateRef gate) const428 GateType GateAccessor::GetGateType(GateRef gate) const
429 {
430 return circuit_->LoadGatePtr(gate)->GetGateType();
431 }
432
SetGateType(GateRef gate,GateType gt)433 void GateAccessor::SetGateType(GateRef gate, GateType gt)
434 {
435 circuit_->LoadGatePtr(gate)->SetGateType(gt);
436 }
437
DeleteExceptionDep(const UseIterator & useIt)438 UseIterator GateAccessor::DeleteExceptionDep(const UseIterator &useIt)
439 {
440 auto next = useIt;
441 next++;
442 ASSERT(GetOpCode(*useIt) == OpCode::RETURN || GetOpCode(*useIt) == OpCode::DEPEND_SELECTOR);
443 if (GetOpCode(*useIt) == OpCode::RETURN) {
444 DeleteGate(useIt);
445 } else {
446 size_t idx = useIt.GetIndex();
447 auto merge = GetState(*useIt, 0);
448 circuit_->DecreaseIn(merge, idx - 1);
449 auto mergeUses = Uses(merge);
450 for (auto useGate : mergeUses) {
451 if (circuit_->GetOpCode(useGate) == OpCode::VALUE_SELECTOR) {
452 circuit_->DecreaseIn(useGate, idx);
453 }
454 }
455 DecreaseIn(useIt);
456 }
457 return next;
458 }
459
DeleteGate(const UseIterator & useIt)460 UseIterator GateAccessor::DeleteGate(const UseIterator &useIt)
461 {
462 auto next = useIt;
463 next++;
464 circuit_->DeleteGate(*useIt);
465 return next;
466 }
467
DecreaseIn(const UseIterator & useIt)468 void GateAccessor::DecreaseIn(const UseIterator &useIt)
469 {
470 size_t idx = useIt.GetIndex();
471 circuit_->DecreaseIn(*useIt, idx);
472 }
473
474
DecreaseIn(GateRef gate,size_t index)475 void GateAccessor::DecreaseIn(GateRef gate, size_t index)
476 {
477 circuit_->DecreaseIn(gate, index);
478 }
479
NewIn(GateRef gate,size_t idx,GateRef in)480 void GateAccessor::NewIn(GateRef gate, size_t idx, GateRef in)
481 {
482 circuit_->NewIn(gate, idx, in);
483 }
484
GetStateCount(GateRef gate) const485 size_t GateAccessor::GetStateCount(GateRef gate) const
486 {
487 return circuit_->LoadGatePtr(gate)->GetStateCount();
488 }
489
GetDependCount(GateRef gate) const490 size_t GateAccessor::GetDependCount(GateRef gate) const
491 {
492 return circuit_->LoadGatePtr(gate)->GetDependCount();
493 }
494
GetInValueCount(GateRef gate) const495 size_t GateAccessor::GetInValueCount(GateRef gate) const
496 {
497 return circuit_->LoadGatePtr(gate)->GetInValueCount();
498 }
499
UpdateAllUses(GateRef oldIn,GateRef newIn)500 void GateAccessor::UpdateAllUses(GateRef oldIn, GateRef newIn)
501 {
502 auto uses = Uses(oldIn);
503 for (auto useIt = uses.begin(); useIt != uses.end();) {
504 useIt = ReplaceIn(useIt, newIn);
505 }
506 }
507
ReplaceIn(GateRef gate,size_t index,GateRef in)508 void GateAccessor::ReplaceIn(GateRef gate, size_t index, GateRef in)
509 {
510 circuit_->ModifyIn(gate, index, in);
511 }
512
DeleteIn(GateRef gate,size_t idx)513 void GateAccessor::DeleteIn(GateRef gate, size_t idx)
514 {
515 ASSERT(idx < circuit_->LoadGatePtrConst(gate)->GetNumIns());
516 ASSERT(!circuit_->IsInGateNull(gate, idx));
517 circuit_->LoadGatePtr(gate)->DeleteIn(idx);
518 }
519
ReplaceStateIn(GateRef gate,GateRef in,size_t index)520 void GateAccessor::ReplaceStateIn(GateRef gate, GateRef in, size_t index)
521 {
522 ASSERT(index < GetStateCount(gate));
523 circuit_->ModifyIn(gate, index, in);
524 }
525
ReplaceDependIn(GateRef gate,GateRef in,size_t index)526 void GateAccessor::ReplaceDependIn(GateRef gate, GateRef in, size_t index)
527 {
528 ASSERT(index < GetDependCount(gate));
529 size_t stateCount = GetStateCount(gate);
530 circuit_->ModifyIn(gate, stateCount + index, in);
531 }
532
ReplaceValueIn(GateRef gate,GateRef in,size_t index)533 void GateAccessor::ReplaceValueIn(GateRef gate, GateRef in, size_t index)
534 {
535 ASSERT(index < GetInValueCount(gate));
536 size_t valueStartIndex = GetInValueStarts(gate);
537 circuit_->ModifyIn(gate, valueStartIndex + index, in);
538 }
539
DeleteGate(GateRef gate)540 void GateAccessor::DeleteGate(GateRef gate)
541 {
542 circuit_->DeleteGate(gate);
543 }
544
GetMachineType(GateRef gate) const545 MachineType GateAccessor::GetMachineType(GateRef gate) const
546 {
547 return circuit_->GetMachineType(gate);
548 }
549
SetMachineType(GateRef gate,MachineType type)550 void GateAccessor::SetMachineType(GateRef gate, MachineType type)
551 {
552 circuit_->SetMachineType(gate, type);
553 }
554
GetConstantGate(MachineType bitValue,BitField bitfield,GateType type) const555 GateRef GateAccessor::GetConstantGate(MachineType bitValue, BitField bitfield, GateType type) const
556 {
557 return circuit_->GetConstantGate(bitValue, bitfield, type);
558 }
559
IsStateIn(const UseIterator & useIt) const560 bool GateAccessor::IsStateIn(const UseIterator &useIt) const
561 {
562 size_t stateStartIndex = 0;
563 size_t stateEndIndex = stateStartIndex + GetStateCount(*useIt);
564 size_t index = useIt.GetIndex();
565 return (index >= stateStartIndex && index < stateEndIndex);
566 }
567
IsDependIn(const UseIterator & useIt) const568 bool GateAccessor::IsDependIn(const UseIterator &useIt) const
569 {
570 size_t dependStartIndex = GetStateCount(*useIt);
571 size_t dependEndIndex = dependStartIndex + GetDependCount(*useIt);
572 size_t index = useIt.GetIndex();
573 return (index >= dependStartIndex && index < dependEndIndex);
574 }
575
IsValueIn(const UseIterator & useIt) const576 bool GateAccessor::IsValueIn(const UseIterator &useIt) const
577 {
578 size_t valueStartIndex = GetInValueStarts(*useIt);
579 size_t valueEndIndex = valueStartIndex + GetInValueCount(*useIt);
580 size_t index = useIt.GetIndex();
581 return (index >= valueStartIndex && index < valueEndIndex);
582 }
583
IsFrameStateIn(const UseIterator & useIt) const584 bool GateAccessor::IsFrameStateIn(const UseIterator &useIt) const
585 {
586 size_t index = useIt.GetIndex();
587 return IsFrameStateIn(*useIt, index);
588 }
589
IsExceptionState(const UseIterator & useIt) const590 bool GateAccessor::IsExceptionState(const UseIterator &useIt) const
591 {
592 auto op = GetOpCode(*useIt);
593 bool isDependSelector = (op == OpCode::DEPEND_SELECTOR) &&
594 (GetOpCode(GetIn(GetIn(*useIt, 0), useIt.GetIndex() - 1)) == OpCode::IF_EXCEPTION);
595 bool isReturn = (op == OpCode::RETURN && GetOpCode(GetIn(*useIt, 0)) == OpCode::IF_EXCEPTION);
596 return isDependSelector || isReturn;
597 }
598
IsDependIn(GateRef gate,size_t index) const599 bool GateAccessor::IsDependIn(GateRef gate, size_t index) const
600 {
601 size_t dependStartIndex = GetStateCount(gate);
602 size_t dependEndIndex = dependStartIndex + GetDependCount(gate);
603 return (index >= dependStartIndex && index < dependEndIndex);
604 }
605
IsValueIn(GateRef gate,size_t index) const606 bool GateAccessor::IsValueIn(GateRef gate, size_t index) const
607 {
608 size_t valueStartIndex = GetInValueStarts(gate);
609 size_t valueEndIndex = valueStartIndex + GetInValueCount(gate);
610 return (index >= valueStartIndex && index < valueEndIndex);
611 }
612
IsFrameStateIn(GateRef gate,size_t index) const613 bool GateAccessor::IsFrameStateIn(GateRef gate, size_t index) const
614 {
615 Gate *gatePtr = circuit_->LoadGatePtr(gate);
616 size_t frameStateStartIndex = gatePtr->GetInFrameStateStarts();
617 size_t FrameStateEndIndex = frameStateStartIndex + gatePtr->GetInFrameStateCount();
618 return (index >= frameStateStartIndex && index < FrameStateEndIndex);
619 }
620
DeleteStateSplitAndFrameState(GateRef gate)621 void GateAccessor::DeleteStateSplitAndFrameState(GateRef gate)
622 {
623 GateRef stateSplit = GetDep(gate);
624 if (GetOpCode(stateSplit) == OpCode::STATE_SPLIT) {
625 GateRef dep = GetDep(stateSplit);
626 ReplaceDependIn(gate, dep);
627 GateRef frameState = GetFrameState(stateSplit);
628 DeleteGate(frameState);
629 DeleteGate(stateSplit);
630 }
631 }
632
ReplaceGate(GateRef gate,GateRef state,GateRef depend,GateRef value)633 void GateAccessor::ReplaceGate(GateRef gate, GateRef state, GateRef depend, GateRef value)
634 {
635 if (value != Circuit::NullGate()) {
636 GateType type = GetGateType(gate);
637 if (!type.IsAnyType()) {
638 SetGateType(value, type);
639 }
640 }
641
642 auto uses = Uses(gate);
643 for (auto useIt = uses.begin(); useIt != uses.end();) {
644 if (IsStateIn(useIt)) {
645 useIt = ReplaceIn(useIt, state);
646 } else if (IsDependIn(useIt)) {
647 useIt = ReplaceIn(useIt, depend);
648 } else if (IsValueIn(useIt)) {
649 useIt = ReplaceIn(useIt, value);
650 } else {
651 UNREACHABLE();
652 }
653 }
654 DeleteGate(gate);
655 }
656
GetFrameState(GateRef gate) const657 GateRef GateAccessor::GetFrameState(GateRef gate) const
658 {
659 ASSERT(HasFrameState(gate));
660 Gate *gatePtr = circuit_->LoadGatePtr(gate);
661 size_t index = gatePtr->GetInFrameStateStarts();
662 return circuit_->GetIn(gate, index);
663 }
664
HasFrameState(GateRef gate) const665 bool GateAccessor::HasFrameState(GateRef gate) const
666 {
667 return GetMetaData(gate)->HasFrameState();
668 }
669
ReplaceFrameStateIn(GateRef gate,GateRef in)670 void GateAccessor::ReplaceFrameStateIn(GateRef gate, GateRef in)
671 {
672 Gate *gatePtr = circuit_->LoadGatePtr(gate);
673 size_t index = gatePtr->GetInFrameStateStarts();
674 circuit_->ModifyIn(gate, index, in);
675 }
676
GetRoot(OpCode opcode) const677 GateRef GateAccessor::GetRoot(OpCode opcode) const
678 {
679 GateRef root = circuit_->GetRoot();
680 if (opcode == OpCode::CIRCUIT_ROOT) {
681 return root;
682 }
683
684 auto uses = ConstUses(root);
685 for (auto useIt = uses.begin(); useIt != uses.end(); ++useIt) {
686 if (GetOpCode(*useIt) == opcode) {
687 return *useIt;
688 }
689 }
690 return Circuit::NullGate();
691 }
692
GetGlueFromArgList() const693 GateRef GateAccessor::GetGlueFromArgList() const
694 {
695 auto argRoot = GetArgRoot();
696 ASSERT(static_cast<size_t>(CommonArgIdx::GLUE) == 0);
697 const Gate *curGate = circuit_->LoadGatePtrConst(argRoot);
698
699 const Out *curOut = curGate->GetFirstOutConst();
700 ASSERT(!curGate->IsFirstOutNull());
701 while (!curOut->IsNextOutNull()) {
702 curOut = curOut->GetNextOutConst();
703 }
704 return circuit_->GetGateRef(curOut->GetGateConst());
705 }
706
GetArgsOuts(std::vector<GateRef> & outs) const707 void GateAccessor::GetArgsOuts(std::vector<GateRef>& outs) const
708 {
709 auto argRoot = GetArgRoot();
710 GetOuts(argRoot, outs);
711 }
712
GetReturnOuts(std::vector<GateRef> & outs) const713 void GateAccessor::GetReturnOuts(std::vector<GateRef>& outs) const
714 {
715 auto returnRoot = GetReturnRoot();
716 GetOuts(returnRoot, outs);
717 }
718
GetMetaData(GateRef gate) const719 const GateMetaData *GateAccessor::GetMetaData(GateRef gate) const
720 {
721 return circuit_->LoadGatePtrConst(gate)->GetMetaData();
722 }
723
SetMetaData(GateRef gate,const GateMetaData * meta)724 void GateAccessor::SetMetaData(GateRef gate, const GateMetaData* meta)
725 {
726 return circuit_->LoadGatePtr(gate)->SetMetaData(meta);
727 }
728 } // namespace panda::ecmascript::kungfu
729