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