1 /*
2 * Copyright (c) 2023 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 "mir_function.h"
17 #include "opcode_info.h"
18 #include "mir_pragma.h"
19 #include "mir_builder.h"
20 #include "bin_mplt.h"
21 #include <sstream>
22 #include <vector>
23
24 using namespace std;
25 namespace maple {
OutputInfoVector(const MIRInfoVector & infoVector,const MapleVector<bool> & infoVectorIsString)26 void BinaryMplExport::OutputInfoVector(const MIRInfoVector &infoVector, const MapleVector<bool> &infoVectorIsString)
27 {
28 if (!mod.IsWithDbgInfo()) {
29 Write(0);
30 return;
31 }
32 WriteNum(infoVector.size());
33 for (uint32 i = 0; i < infoVector.size(); i++) {
34 OutputStr(infoVector[i].first);
35 WriteNum(infoVectorIsString[i] ? 1 : 0);
36 if (!infoVectorIsString[i]) {
37 WriteNum(infoVector[i].second);
38 } else {
39 OutputStr(GStrIdx(infoVector[i].second));
40 }
41 }
42 }
43
OutputFuncIdInfo(MIRFunction * func)44 void BinaryMplExport::OutputFuncIdInfo(MIRFunction *func)
45 {
46 WriteNum(kBinFuncIdInfoStart);
47 WriteNum(func->GetPuidxOrigin()); // the funcid
48 OutputInfoVector(func->GetInfoVector(), func->InfoIsString());
49 if (mod.GetFlavor() == kFlavorLmbc) {
50 WriteNum(func->GetFrameSize());
51 }
52 }
53
OutputBaseNode(const BaseNode * b)54 void BinaryMplExport::OutputBaseNode(const BaseNode *b)
55 {
56 Write(static_cast<uint8>(b->GetOpCode()));
57 Write(static_cast<uint8>(b->GetPrimType()));
58 }
59
OutputLocalSymbol(MIRSymbol * sym)60 void BinaryMplExport::OutputLocalSymbol(MIRSymbol *sym)
61 {
62 std::unordered_map<const MIRSymbol *, int64>::iterator it = localSymMark.find(sym);
63 if (it != localSymMark.end()) {
64 WriteNum(-(it->second));
65 return;
66 }
67
68 WriteNum(kBinSymbol);
69 OutputStr(sym->GetNameStrIdx());
70 WriteNum(sym->GetSKind());
71 WriteNum(sym->GetStorageClass());
72 size_t mark = localSymMark.size();
73 localSymMark[sym] = mark;
74 OutputTypeAttrs(sym->GetAttrs());
75 WriteNum(static_cast<int64>(sym->GetIsTmp()));
76 if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) {
77 OutputSrcPos(sym->GetSrcPosition());
78 }
79 OutputType(sym->GetTyIdx());
80 if (sym->GetSKind() == kStPreg) {
81 OutputPreg(sym->GetPreg());
82 } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) {
83 OutputConst(sym->GetKonst());
84 } else if (sym->GetSKind() == kStFunc) {
85 OutputFuncViaSym(sym->GetFunction()->GetPuidx());
86 } else {
87 CHECK_FATAL(false, "should not used");
88 }
89 }
90
OutputPreg(MIRPreg * preg)91 void BinaryMplExport::OutputPreg(MIRPreg *preg)
92 {
93 if (preg->GetPregNo() < 0) {
94 WriteNum(kBinSpecialReg);
95 Write(static_cast<uint8>(-preg->GetPregNo()));
96 return;
97 }
98 std::unordered_map<const MIRPreg *, int64>::iterator it = localPregMark.find(preg);
99 if (it != localPregMark.end()) {
100 WriteNum(-(it->second));
101 return;
102 }
103
104 WriteNum(kBinPreg);
105 Write(static_cast<uint8>(preg->GetPrimType()));
106 size_t mark = localPregMark.size();
107 localPregMark[preg] = mark;
108 }
109
OutputLabel(LabelIdx lidx)110 void BinaryMplExport::OutputLabel(LabelIdx lidx)
111 {
112 std::unordered_map<LabelIdx, int64>::iterator it = labelMark.find(lidx);
113 if (it != labelMark.end()) {
114 WriteNum(-(it->second));
115 return;
116 }
117
118 WriteNum(kBinLabel);
119 size_t mark = labelMark.size();
120 labelMark[lidx] = mark;
121 }
122
OutputLocalTypeNameTab(const MIRTypeNameTable * typeNameTab)123 void BinaryMplExport::OutputLocalTypeNameTab(const MIRTypeNameTable *typeNameTab)
124 {
125 WriteNum(kBinTypenameStart);
126 WriteNum(static_cast<int64>(typeNameTab->Size()));
127 for (std::pair<GStrIdx, TyIdx> it : typeNameTab->GetGStrIdxToTyIdxMap()) {
128 OutputStr(it.first);
129 OutputType(it.second);
130 }
131 }
132
OutputFormalsStIdx(MIRFunction * func)133 void BinaryMplExport::OutputFormalsStIdx(MIRFunction *func)
134 {
135 WriteNum(kBinFormalStart);
136 WriteNum(func->GetFormalDefVec().size());
137 for (FormalDef formalDef : func->GetFormalDefVec()) {
138 OutputLocalSymbol(formalDef.formalSym);
139 }
140 }
141
OutputAliasMap(MapleMap<GStrIdx,MIRAliasVars> & aliasVarMap)142 void BinaryMplExport::OutputAliasMap(MapleMap<GStrIdx, MIRAliasVars> &aliasVarMap)
143 {
144 WriteNum(kBinAliasMapStart);
145 WriteInt(static_cast<int32>(aliasVarMap.size()));
146 for (std::pair<GStrIdx, MIRAliasVars> it : aliasVarMap) {
147 OutputStr(it.first);
148 OutputStr(it.second.mplStrIdx);
149 OutputType(it.second.tyIdx);
150 OutputStr(it.second.sigStrIdx);
151 }
152 }
153
OutputFuncViaSym(PUIdx puIdx)154 void BinaryMplExport::OutputFuncViaSym(PUIdx puIdx)
155 {
156 MIRFunction *func = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx);
157 MIRSymbol *funcSt = GlobalTables::GetGsymTable().GetSymbolFromStidx(func->GetStIdx().Idx());
158 OutputSymbol(funcSt);
159 }
160
OutputExpression(BaseNode * e)161 void BinaryMplExport::OutputExpression(BaseNode *e)
162 {
163 OutputBaseNode(e);
164 switch (e->GetOpCode()) {
165 // leaf
166 case OP_constval: {
167 MIRConst *constVal = static_cast<ConstvalNode *>(e)->GetConstVal();
168 OutputConst(constVal);
169 return;
170 }
171 case OP_conststr: {
172 UStrIdx strIdx = static_cast<ConststrNode *>(e)->GetStrIdx();
173 OutputUsrStr(strIdx);
174 return;
175 }
176 case OP_addroflabel: {
177 AddroflabelNode *lNode = static_cast<AddroflabelNode *>(e);
178 OutputLabel(lNode->GetOffset());
179 return;
180 }
181 case OP_addroffunc: {
182 AddroffuncNode *addrNode = static_cast<AddroffuncNode *>(e);
183 OutputFuncViaSym(addrNode->GetPUIdx());
184 return;
185 }
186 case OP_sizeoftype: {
187 SizeoftypeNode *sot = static_cast<SizeoftypeNode *>(e);
188 OutputType(sot->GetTyIdx());
189 return;
190 }
191 case OP_addrof:
192 case OP_addrofoff:
193 case OP_dread:
194 case OP_dreadoff: {
195 StIdx stIdx;
196 if (e->GetOpCode() == OP_addrof || e->GetOpCode() == OP_dread) {
197 AddrofNode *drNode = static_cast<AddrofNode *>(e);
198 WriteNum(drNode->GetFieldID());
199 stIdx = drNode->GetStIdx();
200 } else {
201 DreadoffNode *droff = static_cast<DreadoffNode *>(e);
202 WriteNum(droff->offset);
203 stIdx = droff->stIdx;
204 }
205 WriteNum(stIdx.Scope());
206 if (stIdx.Islocal()) {
207 OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx));
208 } else {
209 OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx));
210 }
211 return;
212 }
213 case OP_regread: {
214 RegreadNode *regreadNode = static_cast<RegreadNode *>(e);
215 MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(regreadNode->GetRegIdx());
216 OutputPreg(preg);
217 return;
218 }
219 case OP_gcmalloc:
220 case OP_gcpermalloc:
221 case OP_stackmalloc: {
222 GCMallocNode *gcNode = static_cast<GCMallocNode *>(e);
223 OutputType(gcNode->GetTyIdx());
224 return;
225 }
226 // unary
227 case OP_ceil:
228 case OP_cvt:
229 case OP_floor:
230 case OP_trunc: {
231 TypeCvtNode *typecvtNode = static_cast<TypeCvtNode *>(e);
232 Write(static_cast<uint8>(typecvtNode->FromType()));
233 break;
234 }
235 case OP_retype: {
236 RetypeNode *retypeNode = static_cast<RetypeNode *>(e);
237 OutputType(retypeNode->GetTyIdx());
238 break;
239 }
240 case OP_iread:
241 case OP_iaddrof: {
242 IreadNode *irNode = static_cast<IreadNode *>(e);
243 OutputType(irNode->GetTyIdx());
244 WriteNum(irNode->GetFieldID());
245 break;
246 }
247 case OP_ireadoff: {
248 IreadoffNode *irNode = static_cast<IreadoffNode *>(e);
249 WriteNum(irNode->GetOffset());
250 break;
251 }
252 case OP_ireadfpoff: {
253 IreadFPoffNode *irNode = static_cast<IreadFPoffNode *>(e);
254 WriteNum(irNode->GetOffset());
255 break;
256 }
257 case OP_sext:
258 case OP_zext:
259 case OP_extractbits: {
260 ExtractbitsNode *extNode = static_cast<ExtractbitsNode *>(e);
261 Write(extNode->GetBitsOffset());
262 Write(extNode->GetBitsSize());
263 break;
264 }
265 case OP_depositbits: {
266 DepositbitsNode *dbNode = static_cast<DepositbitsNode *>(e);
267 Write(dbNode->GetBitsOffset());
268 Write(dbNode->GetBitsSize());
269 break;
270 }
271 case OP_gcmallocjarray:
272 case OP_gcpermallocjarray: {
273 JarrayMallocNode *gcNode = static_cast<JarrayMallocNode *>(e);
274 OutputType(gcNode->GetTyIdx());
275 break;
276 }
277 // binary
278 case OP_sub:
279 case OP_mul:
280 case OP_div:
281 case OP_rem:
282 case OP_ashr:
283 case OP_lshr:
284 case OP_shl:
285 case OP_max:
286 case OP_min:
287 case OP_band:
288 case OP_bior:
289 case OP_bxor:
290 case OP_cand:
291 case OP_cior:
292 case OP_land:
293 case OP_lior:
294 case OP_add: {
295 break;
296 }
297 case OP_eq:
298 case OP_ne:
299 case OP_lt:
300 case OP_gt:
301 case OP_le:
302 case OP_ge:
303 case OP_cmpg:
304 case OP_cmpl:
305 case OP_cmp: {
306 CompareNode *cmpNode = static_cast<CompareNode *>(e);
307 Write(static_cast<uint8>(cmpNode->GetOpndType()));
308 break;
309 }
310 case OP_resolveinterfacefunc:
311 case OP_resolvevirtualfunc: {
312 ResolveFuncNode *rsNode = static_cast<ResolveFuncNode *>(e);
313 OutputFuncViaSym(rsNode->GetPuIdx());
314 break;
315 }
316 // ternary
317 case OP_select: {
318 break;
319 }
320 // nary
321 case OP_array: {
322 ArrayNode *arrNode = static_cast<ArrayNode *>(e);
323 OutputType(arrNode->GetTyIdx());
324 Write(static_cast<int8>(arrNode->GetBoundsCheck()));
325 WriteNum(static_cast<int64>(arrNode->NumOpnds()));
326 break;
327 }
328 case OP_intrinsicop: {
329 IntrinsicopNode *intrnNode = static_cast<IntrinsicopNode *>(e);
330 WriteNum(intrnNode->GetIntrinsic());
331 WriteNum(static_cast<int64>(intrnNode->NumOpnds()));
332 break;
333 }
334 case OP_intrinsicopwithtype: {
335 IntrinsicopNode *intrnNode = static_cast<IntrinsicopNode *>(e);
336 WriteNum(intrnNode->GetIntrinsic());
337 OutputType(intrnNode->GetTyIdx());
338 WriteNum(static_cast<int64>(intrnNode->NumOpnds()));
339 break;
340 }
341 default:
342 break;
343 }
344 for (uint32 i = 0; i < e->NumOpnds(); ++i) {
345 OutputExpression(e->Opnd(i));
346 }
347 }
348
349 static SrcPosition lastOutputSrcPosition;
350
OutputSrcPos(const SrcPosition & pos)351 void BinaryMplExport::OutputSrcPos(const SrcPosition &pos)
352 {
353 if (!mod.IsWithDbgInfo()) {
354 return;
355 }
356 if (pos.FileNum() == 0 || pos.LineNum() == 0) { // error case, so output 0
357 WriteNum(lastOutputSrcPosition.RawData());
358 WriteNum(lastOutputSrcPosition.LineNum());
359 return;
360 }
361 WriteNum(pos.RawData());
362 WriteNum(pos.LineNum());
363 lastOutputSrcPosition = pos;
364 }
365
OutputReturnValues(const CallReturnVector * retv)366 void BinaryMplExport::OutputReturnValues(const CallReturnVector *retv)
367 {
368 WriteNum(kBinReturnvals);
369 WriteNum(static_cast<int64>(retv->size()));
370 for (uint32 i = 0; i < retv->size(); i++) {
371 RegFieldPair rfp = (*retv)[i].second;
372 if (rfp.IsReg()) {
373 MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rfp.GetPregIdx());
374 OutputPreg(preg);
375 } else {
376 WriteNum(0);
377 WriteNum((rfp.GetFieldID()));
378 OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol((*retv)[i].first));
379 }
380 }
381 }
382
OutputBlockNode(BlockNode * block)383 void BinaryMplExport::OutputBlockNode(BlockNode *block)
384 {
385 WriteNum(kBinNodeBlock);
386 if (!block->GetStmtNodes().empty()) {
387 OutputSrcPos(block->GetSrcPos());
388 } else {
389 OutputSrcPos(SrcPosition()); // output 0
390 }
391 int32 num = 0;
392 uint64 idx = buf.size();
393 ExpandFourBuffSize(); // place holder, Fixup later
394 for (StmtNode *s = block->GetFirst(); s; s = s->GetNext()) {
395 bool doneWithOpnds = false;
396 OutputSrcPos(s->GetSrcPos());
397 WriteNum(s->GetOpCode());
398 switch (s->GetOpCode()) {
399 case OP_dassign:
400 case OP_dassignoff: {
401 StIdx stIdx;
402 if (s->GetOpCode() == OP_dassign) {
403 DassignNode *dass = static_cast<DassignNode *>(s);
404 WriteNum(dass->GetFieldID());
405 stIdx = dass->GetStIdx();
406 } else {
407 DassignoffNode *dassoff = static_cast<DassignoffNode *>(s);
408 WriteNum(dassoff->GetPrimType());
409 WriteNum(dassoff->offset);
410 stIdx = dassoff->stIdx;
411 }
412 WriteNum(stIdx.Scope());
413 if (stIdx.Islocal()) {
414 OutputLocalSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx));
415 } else {
416 OutputSymbol(curFunc->GetLocalOrGlobalSymbol(stIdx));
417 }
418 break;
419 }
420 case OP_regassign: {
421 RegassignNode *rass = static_cast<RegassignNode *>(s);
422 Write(static_cast<uint8>(rass->GetPrimType()));
423 MIRPreg *preg = curFunc->GetPregTab()->PregFromPregIdx(rass->GetRegIdx());
424 OutputPreg(preg);
425 break;
426 }
427 case OP_iassign: {
428 IassignNode *iass = static_cast<IassignNode *>(s);
429 OutputType(iass->GetTyIdx());
430 WriteNum(iass->GetFieldID());
431 break;
432 }
433 case OP_iassignoff: {
434 IassignoffNode *iassoff = static_cast<IassignoffNode *>(s);
435 Write(static_cast<uint8>(iassoff->GetPrimType()));
436 WriteNum(iassoff->GetOffset());
437 break;
438 }
439 case OP_iassignspoff:
440 case OP_iassignfpoff: {
441 IassignFPoffNode *iassfpoff = static_cast<IassignFPoffNode *>(s);
442 Write(static_cast<uint8>(iassfpoff->GetPrimType()));
443 WriteNum(iassfpoff->GetOffset());
444 break;
445 }
446 case OP_blkassignoff: {
447 BlkassignoffNode *bass = static_cast<BlkassignoffNode *>(s);
448 int32 offsetAlign = (bass->offset << 4) | bass->alignLog2;
449 WriteNum(offsetAlign);
450 WriteNum(bass->blockSize);
451 break;
452 }
453 case OP_call:
454 case OP_virtualcall:
455 case OP_virtualicall:
456 case OP_superclasscall:
457 case OP_interfacecall:
458 case OP_interfaceicall:
459 case OP_customcall:
460 case OP_polymorphiccall: {
461 CallNode *callnode = static_cast<CallNode *>(s);
462 OutputFuncViaSym(callnode->GetPUIdx());
463 if (s->GetOpCode() == OP_polymorphiccall) {
464 OutputType(static_cast<CallNode *>(callnode)->GetTyIdx());
465 }
466 WriteNum(static_cast<int64>(s->NumOpnds()));
467 break;
468 }
469 case OP_callassigned:
470 case OP_virtualcallassigned:
471 case OP_virtualicallassigned:
472 case OP_superclasscallassigned:
473 case OP_interfacecallassigned:
474 case OP_interfaceicallassigned:
475 case OP_customcallassigned: {
476 CallNode *callnode = static_cast<CallNode *>(s);
477 OutputFuncViaSym(callnode->GetPUIdx());
478 OutputReturnValues(&callnode->GetReturnVec());
479 WriteNum(static_cast<int64>(s->NumOpnds()));
480 break;
481 }
482 case OP_polymorphiccallassigned: {
483 CallNode *callnode = static_cast<CallNode *>(s);
484 OutputFuncViaSym(callnode->GetPUIdx());
485 OutputType(callnode->GetTyIdx());
486 OutputReturnValues(&callnode->GetReturnVec());
487 WriteNum(static_cast<int64>(s->NumOpnds()));
488 break;
489 }
490 case OP_icallproto:
491 case OP_icall: {
492 IcallNode *icallnode = static_cast<IcallNode *>(s);
493 OutputType(icallnode->GetRetTyIdx());
494 WriteNum(static_cast<int64>(s->NumOpnds()));
495 break;
496 }
497 case OP_icallprotoassigned:
498 case OP_icallassigned: {
499 IcallNode *icallnode = static_cast<IcallNode *>(s);
500 OutputType(icallnode->GetRetTyIdx());
501 OutputReturnValues(&icallnode->GetReturnVec());
502 WriteNum(static_cast<int64>(s->NumOpnds()));
503 break;
504 }
505 case OP_intrinsiccall:
506 case OP_xintrinsiccall: {
507 IntrinsiccallNode *intrnNode = static_cast<IntrinsiccallNode *>(s);
508 WriteNum(intrnNode->GetIntrinsic());
509 WriteNum(static_cast<int64>(s->NumOpnds()));
510 break;
511 }
512 case OP_intrinsiccallassigned:
513 case OP_xintrinsiccallassigned: {
514 IntrinsiccallNode *intrnNode = static_cast<IntrinsiccallNode *>(s);
515 WriteNum(intrnNode->GetIntrinsic());
516 OutputReturnValues(&intrnNode->GetReturnVec());
517 WriteNum(static_cast<int64>(s->NumOpnds()));
518 break;
519 }
520 case OP_intrinsiccallwithtype: {
521 IntrinsiccallNode *intrnNode = static_cast<IntrinsiccallNode *>(s);
522 WriteNum(intrnNode->GetIntrinsic());
523 OutputType(intrnNode->GetTyIdx());
524 WriteNum(static_cast<int64>(s->NumOpnds()));
525 break;
526 }
527 case OP_intrinsiccallwithtypeassigned: {
528 IntrinsiccallNode *intrnNode = static_cast<IntrinsiccallNode *>(s);
529 WriteNum(intrnNode->GetIntrinsic());
530 OutputType(intrnNode->GetTyIdx());
531 OutputReturnValues(&intrnNode->GetReturnVec());
532 WriteNum(static_cast<int64>(s->NumOpnds()));
533 break;
534 }
535 case OP_syncenter:
536 case OP_syncexit:
537 case OP_return: {
538 WriteNum(static_cast<int64>(s->NumOpnds()));
539 break;
540 }
541 case OP_jscatch:
542 case OP_cppcatch:
543 case OP_finally:
544 case OP_endtry:
545 case OP_cleanuptry:
546 case OP_retsub:
547 case OP_membaracquire:
548 case OP_membarrelease:
549 case OP_membarstorestore:
550 case OP_membarstoreload: {
551 break;
552 }
553 case OP_eval:
554 case OP_throw:
555 case OP_free:
556 case OP_decref:
557 case OP_incref:
558 case OP_decrefreset:
559 CASE_OP_ASSERT_NONNULL
560 case OP_igoto: {
561 break;
562 }
563 case OP_label: {
564 LabelNode *lNode = static_cast<LabelNode *>(s);
565 OutputLabel(lNode->GetLabelIdx());
566 break;
567 }
568 case OP_goto:
569 case OP_gosub: {
570 GotoNode *gtoNode = static_cast<GotoNode *>(s);
571 OutputLabel(gtoNode->GetOffset());
572 break;
573 }
574 case OP_brfalse:
575 case OP_brtrue: {
576 CondGotoNode *cgotoNode = static_cast<CondGotoNode *>(s);
577 OutputLabel(cgotoNode->GetOffset());
578 break;
579 }
580 case OP_switch: {
581 SwitchNode *swNode = static_cast<SwitchNode *>(s);
582 OutputLabel(swNode->GetDefaultLabel());
583 WriteNum(static_cast<int64>(swNode->GetSwitchTable().size()));
584 for (CasePair cpair : swNode->GetSwitchTable()) {
585 WriteNum(cpair.first);
586 OutputLabel(cpair.second);
587 }
588 break;
589 }
590 case OP_rangegoto: {
591 RangeGotoNode *rgoto = static_cast<RangeGotoNode *>(s);
592 WriteNum(rgoto->GetTagOffset());
593 WriteNum(static_cast<int64>(rgoto->GetRangeGotoTable().size()));
594 for (SmallCasePair cpair : rgoto->GetRangeGotoTable()) {
595 WriteNum(cpair.first);
596 OutputLabel(cpair.second);
597 }
598 break;
599 }
600 case OP_jstry: {
601 JsTryNode *tryNode = static_cast<JsTryNode *>(s);
602 OutputLabel(tryNode->GetCatchOffset());
603 OutputLabel(tryNode->GetFinallyOffset());
604 break;
605 }
606 case OP_cpptry:
607 case OP_try: {
608 TryNode *tryNode = static_cast<TryNode *>(s);
609 WriteNum(static_cast<int64>(tryNode->GetOffsetsCount()));
610 for (LabelIdx lidx : tryNode->GetOffsets()) {
611 OutputLabel(lidx);
612 }
613 break;
614 }
615 case OP_catch: {
616 CatchNode *catchNode = static_cast<CatchNode *>(s);
617 WriteNum(static_cast<int64>(catchNode->GetExceptionTyIdxVec().size()));
618 for (TyIdx tidx : catchNode->GetExceptionTyIdxVec()) {
619 OutputType(tidx);
620 }
621 break;
622 }
623 case OP_comment: {
624 string str(static_cast<CommentNode *>(s)->GetComment().c_str());
625 WriteAsciiStr(str);
626 break;
627 }
628 case OP_dowhile:
629 case OP_while: {
630 WhileStmtNode *whileNode = static_cast<WhileStmtNode *>(s);
631 OutputBlockNode(whileNode->GetBody());
632 OutputExpression(whileNode->Opnd());
633 doneWithOpnds = true;
634 break;
635 }
636 case OP_if: {
637 IfStmtNode *ifNode = static_cast<IfStmtNode *>(s);
638 bool hasElsePart = ifNode->GetElsePart() != nullptr;
639 WriteNum(static_cast<int64>(hasElsePart));
640 OutputBlockNode(ifNode->GetThenPart());
641 if (hasElsePart) {
642 OutputBlockNode(ifNode->GetElsePart());
643 }
644 OutputExpression(ifNode->Opnd());
645 doneWithOpnds = true;
646 break;
647 }
648 case OP_block: {
649 BlockNode *blockNode = static_cast<BlockNode *>(s);
650 OutputBlockNode(blockNode);
651 doneWithOpnds = true;
652 break;
653 }
654 case OP_asm: {
655 AsmNode *asmNode = static_cast<AsmNode *>(s);
656 WriteNum(asmNode->qualifiers);
657 string str(asmNode->asmString.c_str());
658 WriteAsciiStr(str);
659 // the outputs
660 size_t count = asmNode->asmOutputs.size();
661 WriteNum(static_cast<int64>(count));
662 for (size_t i = 0; i < count; ++i) {
663 OutputUsrStr(asmNode->outputConstraints[i]);
664 }
665 OutputReturnValues(&asmNode->asmOutputs);
666 // the clobber list
667 count = asmNode->clobberList.size();
668 WriteNum(static_cast<int64>(count));
669 for (size_t i = 0; i < count; ++i) {
670 OutputUsrStr(asmNode->clobberList[i]);
671 }
672 // the labels
673 count = asmNode->gotoLabels.size();
674 WriteNum(static_cast<int64>(count));
675 for (size_t i = 0; i < count; ++i) {
676 OutputLabel(asmNode->gotoLabels[i]);
677 }
678 // the inputs
679 WriteNum(asmNode->NumOpnds());
680 for (uint8 i = 0; i < asmNode->numOpnds; ++i) {
681 OutputUsrStr(asmNode->inputConstraints[i]);
682 }
683 break;
684 }
685 default:
686 CHECK_FATAL(false, "Unhandled opcode %d", s->GetOpCode());
687 break;
688 }
689 num++;
690 if (!doneWithOpnds) {
691 for (uint32 i = 0; i < s->NumOpnds(); ++i) {
692 OutputExpression(s->Opnd(i));
693 }
694 }
695 }
696 Fixup(idx, num);
697 }
698
WriteFunctionBodyField(uint64 contentIdx,std::unordered_set<std::string> * dumpFuncSet)699 void BinaryMplExport::WriteFunctionBodyField(uint64 contentIdx, std::unordered_set<std::string> *dumpFuncSet)
700 {
701 Fixup(contentIdx, static_cast<int32>(buf.size()));
702 WriteNum(kBinFunctionBodyStart);
703 uint64 totalSizeIdx = buf.size();
704 ExpandFourBuffSize(); /// total size of this field to ~BIN_FUNCTIONBODY_START
705 uint64 outFunctionBodySizeIdx = buf.size();
706 ExpandFourBuffSize(); /// size of outFunctionBody
707 int32 size = 0;
708
709 if (not2mplt) {
710 for (MIRFunction *func : GetMIRModule().GetFunctionList()) {
711 curFunc = func;
712 if (func->GetAttr(FUNCATTR_optimized)) {
713 continue;
714 }
715 if (func->GetCodeMemPool() == nullptr || func->GetBody() == nullptr) {
716 continue;
717 }
718 if (dumpFuncSet != nullptr && !dumpFuncSet->empty()) {
719 // output only if this func matches any name in *dumpFuncSet
720 const std::string &name = func->GetName();
721 bool matched = false;
722 for (std::string elem : *dumpFuncSet) {
723 if (name.find(elem.c_str()) != string::npos) {
724 matched = true;
725 break;
726 }
727 }
728 if (!matched) {
729 continue;
730 }
731 }
732 localSymMark.clear();
733 localSymMark[nullptr] = 0;
734 localPregMark.clear();
735 localPregMark[nullptr] = 0;
736 labelMark.clear();
737 labelMark[0] = 0;
738 OutputFunction(func->GetPuidx());
739 CHECK_FATAL(func->GetBody() != nullptr, "WriteFunctionBodyField: no function body");
740 OutputFuncIdInfo(func);
741 OutputLocalTypeNameTab(func->GetTypeNameTab());
742 OutputFormalsStIdx(func);
743 if (mod.GetFlavor() < kMmpl) {
744 OutputAliasMap(func->GetAliasVarMap());
745 }
746 lastOutputSrcPosition = SrcPosition();
747 OutputBlockNode(func->GetBody());
748 size++;
749 }
750 }
751
752 Fixup(totalSizeIdx, static_cast<int32>(buf.size() - totalSizeIdx));
753 Fixup(outFunctionBodySizeIdx, size);
754 return;
755 }
756 } // namespace maple
757