• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "bin_mpl_export.h"
17 #include "bin_mpl_import.h"
18 #include "mir_function.h"
19 #include "opcode_info.h"
20 #include "mir_pragma.h"
21 #include "mir_builder.h"
22 using namespace std;
23 
24 namespace maple {
25 constexpr uint32 kOffset4bit = 4;
ImportInfoVector(MIRInfoVector & infoVector,MapleVector<bool> & infoVectorIsString)26 void BinaryMplImport::ImportInfoVector(MIRInfoVector &infoVector, MapleVector<bool> &infoVectorIsString)
27 {
28     int64 size = ReadNum();
29     for (int64 i = 0; i < size; ++i) {
30         GStrIdx gStrIdx = ImportStr();
31         bool isstring = (ReadNum() != 0);
32         infoVectorIsString.push_back(isstring);
33         if (isstring) {
34             GStrIdx fieldval = ImportStr();
35             infoVector.emplace_back(MIRInfoPair(gStrIdx, fieldval.GetIdx()));
36         } else {
37             auto fieldval = static_cast<uint32>(ReadNum());
38             infoVector.emplace_back(MIRInfoPair(gStrIdx, fieldval));
39         }
40     }
41 }
42 
ImportFuncIdInfo(MIRFunction * func)43 void BinaryMplImport::ImportFuncIdInfo(MIRFunction *func)
44 {
45     int64 tag = ReadNum();
46     CHECK_FATAL(tag == kBinFuncIdInfoStart, "kBinFuncIdInfoStart expected");
47     func->SetPuidxOrigin(static_cast<PUIdx>(ReadNum()));
48     ImportInfoVector(func->GetInfoVector(), func->InfoIsString());
49     if (mod.GetFlavor() == kFlavorLmbc) {
50         func->SetFrameSize(static_cast<uint16>(ReadNum()));
51     }
52 }
53 
ImportBaseNode(Opcode & o,PrimType & typ)54 void BinaryMplImport::ImportBaseNode(Opcode &o, PrimType &typ)
55 {
56     o = static_cast<Opcode>(Read());
57     typ = static_cast<PrimType>(Read());
58 }
59 
ImportLocalSymbol(MIRFunction * func)60 MIRSymbol *BinaryMplImport::ImportLocalSymbol(MIRFunction *func)
61 {
62     int64 tag = ReadNum();
63     if (tag == 0) {
64         return nullptr;
65     }
66     if (tag < 0) {
67         CHECK_FATAL(static_cast<size_t>(-tag) < localSymTab.size(), "index out of bounds");
68         return localSymTab.at(static_cast<size_t>(-tag));
69     }
70     CHECK_FATAL(tag == kBinSymbol, "expecting kBinSymbol in ImportLocalSymbol()");
71     MIRSymbol *sym = func->GetSymTab()->CreateSymbol(kScopeLocal);
72     localSymTab.push_back(sym);
73     sym->SetNameStrIdx(ImportStr());
74     (void)func->GetSymTab()->AddToStringSymbolMap(*sym);
75     sym->SetSKind(static_cast<MIRSymKind>(ReadNum()));
76     sym->SetStorageClass(static_cast<MIRStorageClass>(ReadNum()));
77     sym->SetAttrs(ImportTypeAttrs());
78     sym->SetIsTmp(ReadNum() != 0);
79     if (sym->GetSKind() == kStVar || sym->GetSKind() == kStFunc) {
80         ImportSrcPos(sym->GetSrcPosition());
81     }
82     sym->SetTyIdx(ImportType());
83     if (sym->GetSKind() == kStPreg) {
84         PregIdx pregidx = ImportPreg(func);
85         MIRPreg *preg = func->GetPregTab()->PregFromPregIdx(pregidx);
86         sym->SetPreg(preg);
87     } else if (sym->GetSKind() == kStConst || sym->GetSKind() == kStVar) {
88         sym->SetKonst(ImportConst(func));
89     } else if (sym->GetSKind() == kStFunc) {
90         PUIdx puIdx = ImportFuncViaSym(func);
91         sym->SetFunction(GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx));
92     }
93     return sym;
94 }
95 
ImportPreg(MIRFunction * func)96 PregIdx BinaryMplImport::ImportPreg(MIRFunction *func)
97 {
98     int64 tag = ReadNum();
99     if (tag == 0) {
100         return 0;
101     }
102     if (tag == kBinSpecialReg) {
103         return -Read();
104     }
105     if (tag < 0) {
106         CHECK_FATAL(static_cast<size_t>(-tag) < localPregTab.size(), "index out of bounds");
107         return localPregTab.at(static_cast<size_t>(-tag));
108     }
109     CHECK_FATAL(tag == kBinPreg, "expecting kBinPreg in ImportPreg()");
110 
111     PrimType primType = static_cast<PrimType>(Read());
112     PregIdx pidx = func->GetPregTab()->CreatePreg(primType);
113     localPregTab.push_back(pidx);
114     return pidx;
115 }
116 
ImportLabel(MIRFunction * func)117 LabelIdx BinaryMplImport::ImportLabel(MIRFunction *func)
118 {
119     int64 tag = ReadNum();
120     if (tag == 0) {
121         return 0;
122     }
123     if (tag < 0) {
124         CHECK_FATAL(static_cast<size_t>(-tag) < localLabelTab.size(), "index out of bounds");
125         return localLabelTab.at(static_cast<size_t>(-tag));
126     }
127     CHECK_FATAL(tag == kBinLabel, "kBinLabel expected in ImportLabel()");
128 
129     LabelIdx lidx = func->GetLabelTab()->CreateLabel();
130     localLabelTab.push_back(lidx);
131     return lidx;
132 }
133 
ImportLocalTypeNameTable(MIRTypeNameTable * typeNameTab)134 void BinaryMplImport::ImportLocalTypeNameTable(MIRTypeNameTable *typeNameTab)
135 {
136     int64 tag = ReadNum();
137     CHECK_FATAL(tag == kBinTypenameStart, "kBinTypenameStart expected in ImportLocalTypeNameTable()");
138     int64 size = ReadNum();
139     for (int64 i = 0; i < size; ++i) {
140         GStrIdx strIdx = ImportStr();
141         TyIdx tyIdx = ImportType();
142         typeNameTab->SetGStrIdxToTyIdx(strIdx, tyIdx);
143     }
144 }
145 
ImportFormalsStIdx(MIRFunction * func)146 void BinaryMplImport::ImportFormalsStIdx(MIRFunction *func)
147 {
148     auto tag = ReadNum();
149     CHECK_FATAL(tag == kBinFormalStart, "kBinFormalStart expected in ImportFormalsStIdx()");
150     auto size = ReadNum();
151     for (int64 i = 0; i < size; ++i) {
152         func->GetFormalDefVec()[static_cast<uint64>(i)].formalSym = ImportLocalSymbol(func);
153     }
154 }
155 
ImportAliasMap(MIRFunction * func)156 void BinaryMplImport::ImportAliasMap(MIRFunction *func)
157 {
158     int64 tag = ReadNum();
159     CHECK_FATAL(tag == kBinAliasMapStart, "kBinAliasMapStart expected in ImportAliasMap()");
160     int32 size = ReadInt();
161     for (int32 i = 0; i < size; ++i) {
162         MIRAliasVars aliasvars;
163         GStrIdx strIdx = ImportStr();
164         aliasvars.mplStrIdx = ImportStr();
165         aliasvars.tyIdx = ImportType();
166         (void)ImportStr();  // not assigning to mimic parser
167         func->GetAliasVarMap()[strIdx] = aliasvars;
168     }
169 }
170 
ImportFuncViaSym(MIRFunction * func)171 PUIdx BinaryMplImport::ImportFuncViaSym(MIRFunction *func)
172 {
173     MIRSymbol *sym = InSymbol(func);
174     MIRFunction *f = sym->GetFunction();
175     return f->GetPuidx();
176 }
177 
ImportExpression(MIRFunction * func)178 BaseNode *BinaryMplImport::ImportExpression(MIRFunction *func)
179 {
180     Opcode op;
181     PrimType typ;
182     ImportBaseNode(op, typ);
183     switch (op) {
184         // leaf
185         case OP_constval: {
186             MIRConst *constv = ImportConst(func);
187             ConstvalNode *constNode = mod.CurFuncCodeMemPool()->New<ConstvalNode>(constv);
188             constNode->SetPrimType(typ);
189             return constNode;
190         }
191         case OP_conststr: {
192             UStrIdx strIdx = ImportUsrStr();
193             ConststrNode *constNode = mod.CurFuncCodeMemPool()->New<ConststrNode>(typ, strIdx);
194             constNode->SetPrimType(typ);
195             return constNode;
196         }
197         case OP_addroflabel: {
198             AddroflabelNode *alabNode = mod.CurFuncCodeMemPool()->New<AddroflabelNode>();
199             alabNode->SetOffset(ImportLabel(func));
200             alabNode->SetPrimType(typ);
201             (void)func->GetLabelTab()->addrTakenLabels.insert(alabNode->GetOffset());
202             return alabNode;
203         }
204         case OP_addroffunc: {
205             PUIdx puIdx = ImportFuncViaSym(func);
206             MIRFunction *f = GlobalTables::GetFunctionTable().GetFuncTable()[puIdx];
207             f->GetFuncSymbol()->SetAppearsInCode(true);
208             AddroffuncNode *addrNode = mod.CurFuncCodeMemPool()->New<AddroffuncNode>(typ, puIdx);
209             return addrNode;
210         }
211         case OP_sizeoftype: {
212             TyIdx tidx = ImportType();
213             SizeoftypeNode *sot = mod.CurFuncCodeMemPool()->New<SizeoftypeNode>(tidx);
214             return sot;
215         }
216         case OP_addrof:
217         case OP_addrofoff:
218         case OP_dread:
219         case OP_dreadoff: {
220             int32 num = static_cast<int32>(ReadNum());
221             StIdx stIdx;
222             stIdx.SetScope(static_cast<uint32>(ReadNum()));
223             MIRSymbol *sym = nullptr;
224             if (stIdx.Islocal()) {
225                 sym = ImportLocalSymbol(func);
226                 CHECK_FATAL(sym != nullptr, "null ptr check");
227             } else {
228                 sym = InSymbol(nullptr);
229                 CHECK_FATAL(sym != nullptr, "null ptr check");
230                 if (op == OP_addrof) {
231                     sym->SetHasPotentialAssignment();
232                 }
233             }
234             stIdx.SetIdx(sym->GetStIdx().Idx());
235             if (op == OP_addrof || op == OP_dread) {
236                 AddrofNode *drNode = mod.CurFuncCodeMemPool()->New<AddrofNode>(op);
237                 drNode->SetPrimType(typ);
238                 drNode->SetStIdx(stIdx);
239                 drNode->SetFieldID(num);
240                 return drNode;
241             } else {
242                 DreadoffNode *dreadoff = mod.CurFuncCodeMemPool()->New<DreadoffNode>(op);
243                 dreadoff->SetPrimType(typ);
244                 dreadoff->stIdx = stIdx;
245                 dreadoff->offset = num;
246                 return dreadoff;
247             }
248         }
249         case OP_regread: {
250             RegreadNode *regreadNode = mod.CurFuncCodeMemPool()->New<RegreadNode>();
251             regreadNode->SetRegIdx(ImportPreg(func));
252             regreadNode->SetPrimType(typ);
253             return regreadNode;
254         }
255         case OP_gcmalloc:
256         case OP_gcpermalloc:
257         case OP_stackmalloc: {
258             TyIdx tyIdx = ImportType();
259             GCMallocNode *gcNode = mod.CurFuncCodeMemPool()->New<GCMallocNode>(op, typ, tyIdx);
260             return gcNode;
261         }
262         // unary
263         case OP_abs:
264         case OP_bnot:
265         case OP_lnot:
266         case OP_neg:
267         case OP_recip:
268         case OP_sqrt:
269         case OP_alloca:
270         case OP_malloc: {
271             UnaryNode *unNode = mod.CurFuncCodeMemPool()->New<UnaryNode>(op, typ);
272             unNode->SetOpnd(ImportExpression(func), kFirstOpnd);
273             return unNode;
274         }
275         case OP_ceil:
276         case OP_cvt:
277         case OP_floor:
278         case OP_trunc: {
279             TypeCvtNode *typecvtNode = mod.CurFuncCodeMemPool()->New<TypeCvtNode>(op, typ);
280             typecvtNode->SetFromType(static_cast<PrimType>(Read()));
281             typecvtNode->SetOpnd(ImportExpression(func), kFirstOpnd);
282             return typecvtNode;
283         }
284         case OP_retype: {
285             RetypeNode *retypeNode = mod.CurFuncCodeMemPool()->New<RetypeNode>(typ);
286             retypeNode->SetTyIdx(ImportType());
287             retypeNode->SetOpnd(ImportExpression(func), kFirstOpnd);
288             return retypeNode;
289         }
290         case OP_iread:
291         case OP_iaddrof: {
292             IreadNode *irNode = mod.CurFuncCodeMemPool()->New<IreadNode>(op, typ);
293             irNode->SetTyIdx(ImportType());
294             irNode->SetFieldID(static_cast<FieldID>(ReadNum()));
295             irNode->SetOpnd(ImportExpression(func), kFirstOpnd);
296             return irNode;
297         }
298         case OP_ireadoff: {
299             int32 ofst = static_cast<int32>(ReadNum());
300             IreadoffNode *irNode = mod.CurFuncCodeMemPool()->New<IreadoffNode>(typ, ofst);
301             irNode->SetOpnd(ImportExpression(func), kFirstOpnd);
302             return irNode;
303         }
304         case OP_ireadfpoff: {
305             int32 ofst = static_cast<int32>(ReadNum());
306             IreadFPoffNode *irNode = mod.CurFuncCodeMemPool()->New<IreadFPoffNode>(typ, ofst);
307             return irNode;
308         }
309         case OP_sext:
310         case OP_zext:
311         case OP_extractbits: {
312             ExtractbitsNode *extNode = mod.CurFuncCodeMemPool()->New<ExtractbitsNode>(op, typ);
313             extNode->SetBitsOffset(Read());
314             extNode->SetBitsSize(Read());
315             extNode->SetOpnd(ImportExpression(func), kFirstOpnd);
316             return extNode;
317         }
318         case OP_depositbits: {
319             DepositbitsNode *dbNode = mod.CurFuncCodeMemPool()->New<DepositbitsNode>(op, typ);
320             dbNode->SetBitsOffset(static_cast<uint8>(ReadNum()));
321             dbNode->SetBitsSize(static_cast<uint8>(ReadNum()));
322             dbNode->SetOpnd(ImportExpression(func), kFirstOpnd);
323             dbNode->SetOpnd(ImportExpression(func), kSecondOpnd);
324             return dbNode;
325         }
326         case OP_gcmallocjarray:
327         case OP_gcpermallocjarray: {
328             JarrayMallocNode *gcNode = mod.CurFuncCodeMemPool()->New<JarrayMallocNode>(op, typ);
329             gcNode->SetTyIdx(ImportType());
330             gcNode->SetOpnd(ImportExpression(func), kFirstOpnd);
331             return gcNode;
332         }
333         // binary
334         case OP_sub:
335         case OP_mul:
336         case OP_div:
337         case OP_rem:
338         case OP_ashr:
339         case OP_lshr:
340         case OP_shl:
341         case OP_max:
342         case OP_min:
343         case OP_band:
344         case OP_bior:
345         case OP_bxor:
346         case OP_cand:
347         case OP_cior:
348         case OP_land:
349         case OP_lior:
350         case OP_add: {
351             BinaryNode *binNode = mod.CurFuncCodeMemPool()->New<BinaryNode>(op, typ);
352             binNode->SetOpnd(ImportExpression(func), kFirstOpnd);
353             binNode->SetOpnd(ImportExpression(func), kSecondOpnd);
354             return binNode;
355         }
356         case OP_eq:
357         case OP_ne:
358         case OP_lt:
359         case OP_gt:
360         case OP_le:
361         case OP_ge:
362         case OP_cmpg:
363         case OP_cmpl:
364         case OP_cmp: {
365             CompareNode *cmpNode = mod.CurFuncCodeMemPool()->New<CompareNode>(op, typ);
366             cmpNode->SetOpndType(static_cast<PrimType>(Read()));
367             cmpNode->SetOpnd(ImportExpression(func), kFirstOpnd);
368             cmpNode->SetOpnd(ImportExpression(func), kSecondOpnd);
369             return cmpNode;
370         }
371         case OP_resolveinterfacefunc:
372         case OP_resolvevirtualfunc: {
373             ResolveFuncNode *rsNode = mod.CurFuncCodeMemPool()->New<ResolveFuncNode>(op, typ);
374             rsNode->SetPUIdx(ImportFuncViaSym(func));
375             rsNode->SetOpnd(ImportExpression(func), kFirstOpnd);
376             rsNode->SetOpnd(ImportExpression(func), kSecondOpnd);
377             return rsNode;
378         }
379         // ternary
380         case OP_select: {
381             TernaryNode *tNode = mod.CurFuncCodeMemPool()->New<TernaryNode>(op, typ);
382             tNode->SetOpnd(ImportExpression(func), kFirstOpnd);
383             tNode->SetOpnd(ImportExpression(func), kSecondOpnd);
384             tNode->SetOpnd(ImportExpression(func), kThirdOpnd);
385             return tNode;
386         }
387         // nary
388         case OP_array: {
389             TyIdx tidx = ImportType();
390             bool boundsCheck = static_cast<bool>(Read());
391             ArrayNode *arrNode =
392                 mod.CurFuncCodeMemPool()->New<ArrayNode>(func->GetCodeMPAllocator(), typ, tidx, boundsCheck);
393             auto n = static_cast<uint32>(ReadNum());
394             for (uint32 i = 0; i < n; ++i) {
395                 arrNode->GetNopnd().push_back(ImportExpression(func));
396             }
397             arrNode->SetNumOpnds(static_cast<uint8>(arrNode->GetNopnd().size()));
398             return arrNode;
399         }
400         case OP_intrinsicop: {
401             IntrinsicopNode *intrnNode =
402                 mod.CurFuncCodeMemPool()->New<IntrinsicopNode>(func->GetCodeMPAllocator(), op, typ);
403             intrnNode->SetIntrinsic(static_cast<MIRIntrinsicID>(ReadNum()));
404             auto n = static_cast<uint32>(ReadNum());
405             for (uint32 i = 0; i < n; ++i) {
406                 intrnNode->GetNopnd().push_back(ImportExpression(func));
407             }
408             intrnNode->SetNumOpnds(static_cast<uint8>(intrnNode->GetNopnd().size()));
409             return intrnNode;
410         }
411         case OP_intrinsicopwithtype: {
412             IntrinsicopNode *intrnNode =
413                 mod.CurFuncCodeMemPool()->New<IntrinsicopNode>(func->GetCodeMPAllocator(), OP_intrinsicopwithtype, typ);
414             intrnNode->SetIntrinsic((MIRIntrinsicID)ReadNum());
415             intrnNode->SetTyIdx(ImportType());
416             auto n = static_cast<uint32>(ReadNum());
417             for (uint32 i = 0; i < n; ++i) {
418                 intrnNode->GetNopnd().push_back(ImportExpression(func));
419             }
420             intrnNode->SetNumOpnds(static_cast<uint8>(intrnNode->GetNopnd().size()));
421             return intrnNode;
422         }
423         default:
424             CHECK_FATAL(false, "Unhandled op %d", op);
425             break;
426     }
427 }
428 
ImportSrcPos(SrcPosition & pos)429 void BinaryMplImport::ImportSrcPos(SrcPosition &pos)
430 {
431     if (!mod.IsWithDbgInfo()) {
432         return;
433     }
434     pos.SetRawData(static_cast<uint32>(ReadNum()));
435     pos.SetLineNum(static_cast<uint32>(ReadNum()));
436 }
437 
ImportReturnValues(MIRFunction * func,CallReturnVector * retv)438 void BinaryMplImport::ImportReturnValues(MIRFunction *func, CallReturnVector *retv)
439 {
440     int64 tag = ReadNum();
441     CHECK_FATAL(tag == kBinReturnvals, "expecting return values");
442     auto size = static_cast<uint32>(ReadNum());
443     for (uint32 i = 0; i < size; ++i) {
444         RegFieldPair rfp;
445         rfp.SetPregIdx(ImportPreg(func));
446         if (rfp.IsReg()) {
447             retv->push_back(std::make_pair(StIdx(), rfp));
448             continue;
449         }
450         rfp.SetFieldID(static_cast<FieldID>(ReadNum()));
451         MIRSymbol *lsym = ImportLocalSymbol(func);
452         CHECK_FATAL(lsym != nullptr, "null ptr check");
453         retv->push_back(std::make_pair(lsym->GetStIdx(), rfp));
454         if (lsym->GetName().find("L_STR") == 0) {
455             MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(lsym->GetTyIdx());
456             CHECK_FATAL(ty->GetKind() == kTypePointer, "Pointer type expected for L_STR prefix");
457             MIRPtrType tempType(static_cast<MIRPtrType *>(ty)->GetPointedTyIdx(), PTY_ptr);
458             TyIdx newTyidx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&tempType);
459             lsym->SetTyIdx(newTyidx);
460         }
461     }
462 }
463 
ImportBlockNode(MIRFunction * func)464 BlockNode *BinaryMplImport::ImportBlockNode(MIRFunction *func)
465 {
466     int64 tag = ReadNum();
467     DEBUG_ASSERT(tag == kBinNodeBlock, "expecting a BlockNode");
468 
469     BlockNode *block = func->GetCodeMemPool()->New<BlockNode>();
470     Opcode op;
471     uint8 numOpr;
472     ImportSrcPos(block->GetSrcPos());
473     int32 size = ReadInt();
474     for (int32 k = 0; k < size; ++k) {
475         SrcPosition thesrcPosition;
476         ImportSrcPos(thesrcPosition);
477         op = static_cast<Opcode>(ReadNum());
478         StmtNode *stmt = nullptr;
479         switch (op) {
480             case OP_dassign:
481             case OP_dassignoff: {
482                 PrimType primType = PTY_void;
483                 if (op == OP_dassignoff) {
484                     primType = static_cast<PrimType>(ReadNum());
485                 }
486                 int32 num = static_cast<int32>(ReadNum());
487                 StIdx stIdx;
488                 stIdx.SetScope(static_cast<uint32>(ReadNum()));
489                 MIRSymbol *sym = nullptr;
490                 if (stIdx.Islocal()) {
491                     sym = ImportLocalSymbol(func);
492                     CHECK_FATAL(sym != nullptr, "null ptr check");
493                 } else {
494                     sym = InSymbol(nullptr);
495                     CHECK_FATAL(sym != nullptr, "null ptr check");
496                     sym->SetHasPotentialAssignment();
497                 }
498                 stIdx.SetIdx(sym->GetStIdx().Idx());
499                 if (op == OP_dassign) {
500                     DassignNode *s = func->GetCodeMemPool()->New<DassignNode>();
501                     s->SetStIdx(stIdx);
502                     s->SetFieldID(num);
503                     s->SetOpnd(ImportExpression(func), kFirstOpnd);
504                     stmt = s;
505                 } else {
506                     DassignoffNode *s = func->GetCodeMemPool()->New<DassignoffNode>();
507                     s->SetPrimType(primType);
508                     s->stIdx = stIdx;
509                     s->offset = num;
510                     s->SetOpnd(ImportExpression(func), kFirstOpnd);
511                     stmt = s;
512                 }
513                 break;
514             }
515             case OP_regassign: {
516                 RegassignNode *s = func->GetCodeMemPool()->New<RegassignNode>();
517                 s->SetPrimType(static_cast<PrimType>(Read()));
518                 s->SetRegIdx(ImportPreg(func));
519                 s->SetOpnd(ImportExpression(func), kFirstOpnd);
520                 stmt = s;
521                 break;
522             }
523             case OP_iassign: {
524                 IassignNode *s = func->GetCodeMemPool()->New<IassignNode>();
525                 s->SetTyIdx(ImportType());
526                 s->SetFieldID(static_cast<FieldID>(ReadNum()));
527                 s->SetAddrExpr(ImportExpression(func));
528                 s->SetRHS(ImportExpression(func));
529                 stmt = s;
530                 break;
531             }
532             case OP_iassignoff: {
533                 IassignoffNode *s = func->GetCodeMemPool()->New<IassignoffNode>();
534                 s->SetPrimType((PrimType)Read());
535                 s->SetOffset(static_cast<int32>(ReadNum()));
536                 s->SetOpnd(ImportExpression(func), kFirstOpnd);
537                 s->SetOpnd(ImportExpression(func), kSecondOpnd);
538                 stmt = s;
539                 break;
540             }
541             case OP_iassignspoff:
542             case OP_iassignfpoff: {
543                 IassignFPoffNode *s = func->GetCodeMemPool()->New<IassignFPoffNode>(op);
544                 s->SetPrimType(static_cast<PrimType>(Read()));
545                 s->SetOffset(static_cast<int32>(ReadNum()));
546                 s->SetOpnd(ImportExpression(func), kFirstOpnd);
547                 stmt = s;
548                 break;
549             }
550             case OP_blkassignoff: {
551                 BlkassignoffNode *s = func->GetCodeMemPool()->New<BlkassignoffNode>();
552                 int32 offsetAlign = static_cast<int32>(ReadNum());
553                 s->offset = offsetAlign >> kOffset4bit;
554                 s->alignLog2 = offsetAlign & 0xf;
555                 s->blockSize = static_cast<int32>(ReadNum());
556                 s->SetOpnd(ImportExpression(func), kFirstOpnd);
557                 s->SetOpnd(ImportExpression(func), kSecondOpnd);
558                 stmt = s;
559                 break;
560             }
561             case OP_call:
562             case OP_virtualcall:
563             case OP_virtualicall:
564             case OP_superclasscall:
565             case OP_interfacecall:
566             case OP_interfaceicall:
567             case OP_customcall: {
568                 CallNode *s = func->GetCodeMemPool()->New<CallNode>(mod, op);
569                 s->SetPUIdx(ImportFuncViaSym(func));
570                 MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx());
571                 f->GetFuncSymbol()->SetAppearsInCode(true);
572                 numOpr = static_cast<uint8>(ReadNum());
573                 s->SetNumOpnds(numOpr);
574                 for (int32 i = 0; i < numOpr; ++i) {
575                     s->GetNopnd().push_back(ImportExpression(func));
576                 }
577                 stmt = s;
578                 break;
579             }
580             case OP_callassigned:
581             case OP_virtualcallassigned:
582             case OP_virtualicallassigned:
583             case OP_superclasscallassigned:
584             case OP_interfacecallassigned:
585             case OP_interfaceicallassigned:
586             case OP_customcallassigned: {
587                 CallNode *s = func->GetCodeMemPool()->New<CallNode>(mod, op);
588                 s->SetPUIdx(ImportFuncViaSym(func));
589                 MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx());
590                 f->GetFuncSymbol()->SetAppearsInCode(true);
591                 ImportReturnValues(func, &s->GetReturnVec());
592                 numOpr = static_cast<uint8>(ReadNum());
593                 s->SetNumOpnds(numOpr);
594                 const auto &calleeName =
595                     GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx())->GetName();
596                 if (calleeName == "setjmp") {
597                     func->SetHasSetjmp();
598                 }
599                 for (int32 i = 0; i < numOpr; ++i) {
600                     s->GetNopnd().push_back(ImportExpression(func));
601                 }
602                 stmt = s;
603                 break;
604             }
605             case OP_polymorphiccall: {
606                 CallNode *s = func->GetCodeMemPool()->New<CallNode>(mod, op);
607                 s->SetPUIdx(ImportFuncViaSym(func));
608                 MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx());
609                 f->GetFuncSymbol()->SetAppearsInCode(true);
610                 s->SetTyIdx(ImportType());
611                 numOpr = static_cast<uint8>(ReadNum());
612                 s->SetNumOpnds(numOpr);
613                 for (int32 i = 0; i < numOpr; ++i) {
614                     s->GetNopnd().push_back(ImportExpression(func));
615                 }
616                 stmt = s;
617                 break;
618             }
619             case OP_polymorphiccallassigned: {
620                 CallNode *s = func->GetCodeMemPool()->New<CallNode>(mod, op);
621                 s->SetPUIdx(ImportFuncViaSym(func));
622                 MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(s->GetPUIdx());
623                 f->GetFuncSymbol()->SetAppearsInCode(true);
624                 s->SetTyIdx(ImportType());
625                 ImportReturnValues(func, &s->GetReturnVec());
626                 numOpr = static_cast<uint8>(ReadNum());
627                 s->SetNumOpnds(numOpr);
628                 for (int32 i = 0; i < numOpr; ++i) {
629                     s->GetNopnd().push_back(ImportExpression(func));
630                 }
631                 stmt = s;
632                 break;
633             }
634             case OP_icallproto:
635             case OP_icall: {
636                 IcallNode *s = func->GetCodeMemPool()->New<IcallNode>(mod, op);
637                 s->SetRetTyIdx(ImportType());
638                 numOpr = static_cast<uint8>(ReadNum());
639                 s->SetNumOpnds(numOpr);
640                 for (int32 i = 0; i < numOpr; ++i) {
641                     s->GetNopnd().push_back(ImportExpression(func));
642                 }
643                 stmt = s;
644                 break;
645             }
646             case OP_icallprotoassigned:
647             case OP_icallassigned: {
648                 IcallNode *s = func->GetCodeMemPool()->New<IcallNode>(mod, op);
649                 s->SetRetTyIdx(ImportType());
650                 ImportReturnValues(func, &s->GetReturnVec());
651                 numOpr = static_cast<uint8>(ReadNum());
652                 s->SetNumOpnds(numOpr);
653                 for (int32 i = 0; i < numOpr; ++i) {
654                     s->GetNopnd().push_back(ImportExpression(func));
655                 }
656                 stmt = s;
657                 break;
658             }
659             case OP_intrinsiccall:
660             case OP_xintrinsiccall: {
661                 IntrinsiccallNode *s = func->GetCodeMemPool()->New<IntrinsiccallNode>(mod, op);
662                 s->SetIntrinsic(static_cast<MIRIntrinsicID>(ReadNum()));
663                 numOpr = static_cast<uint8>(ReadNum());
664                 s->SetNumOpnds(numOpr);
665                 for (int32 i = 0; i < numOpr; ++i) {
666                     s->GetNopnd().push_back(ImportExpression(func));
667                 }
668                 stmt = s;
669                 break;
670             }
671             case OP_intrinsiccallassigned:
672             case OP_xintrinsiccallassigned: {
673                 IntrinsiccallNode *s = func->GetCodeMemPool()->New<IntrinsiccallNode>(mod, op);
674                 s->SetIntrinsic((MIRIntrinsicID)ReadNum());
675                 ImportReturnValues(func, &s->GetReturnVec());
676                 numOpr = static_cast<uint8>(ReadNum());
677                 s->SetNumOpnds(numOpr);
678                 for (int32 i = 0; i < numOpr; ++i) {
679                     s->GetNopnd().push_back(ImportExpression(func));
680                 }
681                 if (s->GetReturnVec().size() == 1 && s->GetReturnVec()[0].first.Idx() != 0) {
682                     MIRSymbol *retsymbol = func->GetSymTab()->GetSymbolFromStIdx(s->GetReturnVec()[0].first.Idx());
683                     MIRType *rettype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(retsymbol->GetTyIdx());
684                     CHECK_FATAL(rettype != nullptr, "rettype is null in MIRParser::ParseStmtIntrinsiccallAssigned");
685                     s->SetPrimType(rettype->GetPrimType());
686                 }
687                 stmt = s;
688                 break;
689             }
690             case OP_intrinsiccallwithtype: {
691                 IntrinsiccallNode *s = func->GetCodeMemPool()->New<IntrinsiccallNode>(mod, op);
692                 s->SetIntrinsic((MIRIntrinsicID)ReadNum());
693                 s->SetTyIdx(ImportType());
694                 numOpr = static_cast<uint8>(ReadNum());
695                 s->SetNumOpnds(numOpr);
696                 for (int32 i = 0; i < numOpr; ++i) {
697                     s->GetNopnd().push_back(ImportExpression(func));
698                 }
699                 stmt = s;
700                 break;
701             }
702             case OP_intrinsiccallwithtypeassigned: {
703                 IntrinsiccallNode *s = func->GetCodeMemPool()->New<IntrinsiccallNode>(mod, op);
704                 s->SetIntrinsic((MIRIntrinsicID)ReadNum());
705                 s->SetTyIdx(ImportType());
706                 ImportReturnValues(func, &s->GetReturnVec());
707                 numOpr = static_cast<uint8>(ReadNum());
708                 s->SetNumOpnds(numOpr);
709                 for (int32 i = 0; i < numOpr; ++i) {
710                     s->GetNopnd().push_back(ImportExpression(func));
711                 }
712                 if (s->GetReturnVec().size() == 1 && s->GetReturnVec()[0].first.Idx() != 0) {
713                     MIRSymbol *retsymbol = func->GetSymTab()->GetSymbolFromStIdx(s->GetReturnVec()[0].first.Idx());
714                     MIRType *rettype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(retsymbol->GetTyIdx());
715                     CHECK_FATAL(rettype != nullptr, "rettype is null in MIRParser::ParseStmtIntrinsiccallAssigned");
716                     s->SetPrimType(rettype->GetPrimType());
717                 }
718                 stmt = s;
719                 break;
720             }
721             case OP_syncenter:
722             case OP_syncexit:
723             case OP_return: {
724                 NaryStmtNode *s = func->GetCodeMemPool()->New<NaryStmtNode>(mod, op);
725                 numOpr = static_cast<uint8>(ReadNum());
726                 s->SetNumOpnds(numOpr);
727                 for (int32 i = 0; i < numOpr; ++i) {
728                     s->GetNopnd().push_back(ImportExpression(func));
729                 }
730                 stmt = s;
731                 break;
732             }
733             case OP_jscatch:
734             case OP_cppcatch:
735             case OP_finally:
736             case OP_endtry:
737             case OP_cleanuptry:
738             case OP_retsub:
739             case OP_membaracquire:
740             case OP_membarrelease:
741             case OP_membarstorestore:
742             case OP_membarstoreload: {
743                 stmt = mod.CurFuncCodeMemPool()->New<StmtNode>(op);
744                 break;
745             }
746             case OP_eval:
747             case OP_throw:
748             case OP_free:
749             case OP_decref:
750             case OP_incref:
751             case OP_decrefreset:
752                 CASE_OP_ASSERT_NONNULL
753             case OP_igoto: {
754                 UnaryStmtNode *s = mod.CurFuncCodeMemPool()->New<UnaryStmtNode>(op);
755                 s->SetOpnd(ImportExpression(func), kFirstOpnd);
756                 stmt = s;
757                 break;
758             }
759             case OP_label: {
760                 LabelNode *s = mod.CurFuncCodeMemPool()->New<LabelNode>();
761                 s->SetLabelIdx(ImportLabel(func));
762                 stmt = s;
763                 break;
764             }
765             case OP_goto:
766             case OP_gosub: {
767                 GotoNode *s = mod.CurFuncCodeMemPool()->New<GotoNode>(op);
768                 s->SetOffset(ImportLabel(func));
769                 stmt = s;
770                 break;
771             }
772             case OP_brfalse:
773             case OP_brtrue: {
774                 CondGotoNode *s = mod.CurFuncCodeMemPool()->New<CondGotoNode>(op);
775                 s->SetOffset(ImportLabel(func));
776                 s->SetOpnd(ImportExpression(func), kFirstOpnd);
777                 stmt = s;
778                 break;
779             }
780             case OP_switch: {
781                 SwitchNode *s = mod.CurFuncCodeMemPool()->New<SwitchNode>(mod);
782                 s->SetDefaultLabel(ImportLabel(func));
783                 auto tagSize = static_cast<uint32>(ReadNum());
784                 for (uint32 i = 0; i < tagSize; ++i) {
785                     int64 casetag = ReadNum();
786                     LabelIdx lidx = ImportLabel(func);
787                     CasePair cpair = std::make_pair(casetag, lidx);
788                     s->GetSwitchTable().push_back(cpair);
789                 }
790                 s->SetSwitchOpnd(ImportExpression(func));
791                 stmt = s;
792                 break;
793             }
794             case OP_rangegoto: {
795                 RangeGotoNode *s = mod.CurFuncCodeMemPool()->New<RangeGotoNode>(mod);
796                 s->SetTagOffset(static_cast<int32>(ReadNum()));
797                 uint32 tagSize = static_cast<uint32>(ReadNum());
798                 for (uint32 i = 0; i < tagSize; ++i) {
799                     uint16 casetag = static_cast<uint16>(ReadNum());
800                     LabelIdx lidx = ImportLabel(func);
801                     s->AddRangeGoto(casetag, lidx);
802                 }
803                 s->SetOpnd(ImportExpression(func), kFirstOpnd);
804                 stmt = s;
805                 break;
806             }
807             case OP_jstry: {
808                 JsTryNode *s = mod.CurFuncCodeMemPool()->New<JsTryNode>();
809                 s->SetCatchOffset(ImportLabel(func));
810                 s->SetFinallyOffset(ImportLabel(func));
811                 stmt = s;
812                 break;
813             }
814             case OP_cpptry:
815             case OP_try: {
816                 TryNode *s = mod.CurFuncCodeMemPool()->New<TryNode>(mod);
817                 auto numLabels = static_cast<uint32>(ReadNum());
818                 for (uint32 i = 0; i < numLabels; ++i) {
819                     s->GetOffsets().push_back(ImportLabel(func));
820                 }
821                 stmt = s;
822                 break;
823             }
824             case OP_catch: {
825                 CatchNode *s = mod.CurFuncCodeMemPool()->New<CatchNode>(mod);
826                 auto numTys = static_cast<uint32>(ReadNum());
827                 for (uint32 i = 0; i < numTys; ++i) {
828                     s->PushBack(ImportType());
829                 }
830                 stmt = s;
831                 break;
832             }
833             case OP_comment: {
834                 CommentNode *s = mod.CurFuncCodeMemPool()->New<CommentNode>(mod);
835                 string str;
836                 ReadAsciiStr(str);
837                 s->SetComment(str);
838                 stmt = s;
839                 break;
840             }
841             case OP_dowhile:
842             case OP_while: {
843                 WhileStmtNode *s = mod.CurFuncCodeMemPool()->New<WhileStmtNode>(op);
844                 s->SetBody(ImportBlockNode(func));
845                 s->SetOpnd(ImportExpression(func), kFirstOpnd);
846                 stmt = s;
847                 break;
848             }
849             case OP_if: {
850                 IfStmtNode *s = mod.CurFuncCodeMemPool()->New<IfStmtNode>();
851                 bool hasElsePart = (static_cast<size_t>(ReadNum()) != kFirstOpnd);
852                 s->SetThenPart(ImportBlockNode(func));
853                 if (hasElsePart) {
854                     s->SetElsePart(ImportBlockNode(func));
855                     s->SetNumOpnds(kOperandNumTernary);
856                 }
857                 s->SetOpnd(ImportExpression(func), kFirstOpnd);
858                 stmt = s;
859                 break;
860             }
861             case OP_block: {
862                 stmt = ImportBlockNode(func);
863                 break;
864             }
865             case OP_asm: {
866                 AsmNode *s = mod.CurFuncCodeMemPool()->New<AsmNode>(&mod.GetCurFuncCodeMPAllocator());
867                 mod.CurFunction()->SetHasAsm();
868                 s->qualifiers = static_cast<uint32>(ReadNum());
869                 string str;
870                 ReadAsciiStr(str);
871                 s->asmString = str;
872                 // the outputs
873                 auto count = static_cast<size_t>(ReadNum());
874                 UStrIdx strIdx;
875                 for (size_t i = 0; i < count; ++i) {
876                     strIdx = ImportUsrStr();
877                     s->outputConstraints.push_back(strIdx);
878                 }
879                 ImportReturnValues(func, &s->asmOutputs);
880                 // the clobber list
881                 count = static_cast<size_t>(ReadNum());
882                 for (size_t i = 0; i < count; ++i) {
883                     strIdx = ImportUsrStr();
884                     s->clobberList.push_back(strIdx);
885                 }
886                 // the labels
887                 count = static_cast<size_t>(ReadNum());
888                 for (size_t i = 0; i < count; ++i) {
889                     LabelIdx lidx = ImportLabel(func);
890                     s->gotoLabels.push_back(lidx);
891                 }
892                 // the inputs
893                 numOpr = static_cast<uint8>(ReadNum());
894                 s->SetNumOpnds(numOpr);
895                 for (int32 i = 0; i < numOpr; ++i) {
896                     strIdx = ImportUsrStr();
897                     s->inputConstraints.push_back(strIdx);
898                     const std::string &inStr = GlobalTables::GetUStrTable().GetStringFromStrIdx(strIdx);
899                     if (inStr[0] == '+') {
900                         s->SetHasWriteInputs();
901                     }
902                 }
903                 for (int32 i = 0; i < numOpr; ++i) {
904                     s->GetNopnd().push_back(ImportExpression(func));
905                 }
906                 stmt = s;
907                 break;
908             }
909             default:
910                 CHECK_FATAL(false, "Unhandled opcode tag %d", tag);
911                 break;
912         }
913         stmt->SetSrcPos(thesrcPosition);
914         block->AddStatement(stmt);
915     }
916     if (func != nullptr) {
917         func->SetBody(block);
918     }
919     return block;
920 }
921 
ReadFunctionBodyField()922 void BinaryMplImport::ReadFunctionBodyField()
923 {
924     (void)ReadInt();  /// skip total size
925     int32 size = ReadInt();
926     for (int64 i = 0; i < size; ++i) {
927         PUIdx puIdx = ImportFunction();
928         MIRFunction *fn = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(puIdx);
929         mod.SetCurFunction(fn);
930         fn->GetFuncSymbol()->SetAppearsInCode(true);
931         localSymTab.clear();
932         localSymTab.push_back(nullptr);
933         localPregTab.clear();
934         localPregTab.push_back(0);
935         localLabelTab.clear();
936         localLabelTab.push_back(0);
937 
938         fn->AllocSymTab();
939         fn->AllocPregTab();
940         fn->AllocTypeNameTab();
941         fn->AllocLabelTab();
942 
943         ImportFuncIdInfo(fn);
944         ImportLocalTypeNameTable(fn->GetTypeNameTab());
945         ImportFormalsStIdx(fn);
946         if (mod.GetFlavor() < kMmpl) {
947             ImportAliasMap(fn);
948         }
949         (void)ImportBlockNode(fn);
950         mod.AddFunction(fn);
951     }
952     return;
953 }
954 }  // namespace maple
955