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