1 //===--- Disasm.cpp - Disassembler for bytecode functions -------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // Dump method for Function which disassembles the bytecode. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "Floating.h" 14 #include "Function.h" 15 #include "Opcode.h" 16 #include "PrimType.h" 17 #include "Program.h" 18 #include "clang/AST/DeclCXX.h" 19 #include "llvm/Support/Compiler.h" 20 #include "llvm/Support/Format.h" 21 22 using namespace clang; 23 using namespace clang::interp; 24 25 template <typename T> inline T ReadArg(Program &P, CodePtr &OpPC) { 26 if constexpr (std::is_pointer_v<T>) { 27 uint32_t ID = OpPC.read<uint32_t>(); 28 return reinterpret_cast<T>(P.getNativePointer(ID)); 29 } else { 30 return OpPC.read<T>(); 31 } 32 } 33 34 template <> inline Floating ReadArg<Floating>(Program &P, CodePtr &OpPC) { 35 Floating F = Floating::deserialize(*OpPC); 36 OpPC += align(F.bytesToSerialize()); 37 return F; 38 } 39 40 LLVM_DUMP_METHOD void Function::dump() const { dump(llvm::errs()); } 41 42 LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS) const { 43 OS << getName() << " " << (const void *)this << "\n"; 44 OS << "frame size: " << getFrameSize() << "\n"; 45 OS << "arg size: " << getArgSize() << "\n"; 46 OS << "rvo: " << hasRVO() << "\n"; 47 OS << "this arg: " << hasThisPointer() << "\n"; 48 49 auto PrintName = [&OS](const char *Name) { 50 OS << Name; 51 long N = 30 - strlen(Name); 52 if (N > 0) 53 OS.indent(N); 54 }; 55 56 for (CodePtr Start = getCodeBegin(), PC = Start; PC != getCodeEnd();) { 57 size_t Addr = PC - Start; 58 auto Op = PC.read<Opcode>(); 59 OS << llvm::format("%8d", Addr) << " "; 60 switch (Op) { 61 #define GET_DISASM 62 #include "Opcodes.inc" 63 #undef GET_DISASM 64 } 65 } 66 } 67 68 LLVM_DUMP_METHOD void Program::dump() const { dump(llvm::errs()); } 69 70 LLVM_DUMP_METHOD void Program::dump(llvm::raw_ostream &OS) const { 71 OS << ":: Program\n"; 72 OS << "Global Variables: " << Globals.size() << "\n"; 73 OS << "Functions: " << Funcs.size() << "\n"; 74 OS << "\n"; 75 for (auto &Func : Funcs) { 76 Func.second->dump(); 77 } 78 for (auto &Anon : AnonFuncs) { 79 Anon->dump(); 80 } 81 } 82