• 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 #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