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 
1306c3fb27SDimitry Andric #include "Floating.h"
14a7dea167SDimitry Andric #include "Function.h"
15a7dea167SDimitry Andric #include "Opcode.h"
16a7dea167SDimitry Andric #include "PrimType.h"
17a7dea167SDimitry Andric #include "Program.h"
18a7dea167SDimitry Andric #include "clang/AST/DeclCXX.h"
19a7dea167SDimitry Andric #include "llvm/Support/Compiler.h"
205ffd83dbSDimitry Andric #include "llvm/Support/Format.h"
21a7dea167SDimitry Andric 
22a7dea167SDimitry Andric using namespace clang;
23a7dea167SDimitry Andric using namespace clang::interp;
24a7dea167SDimitry Andric 
ReadArg(Program & P,CodePtr & OpPC)25bdd1243dSDimitry Andric template <typename T> inline T ReadArg(Program &P, CodePtr &OpPC) {
26bdd1243dSDimitry Andric   if constexpr (std::is_pointer_v<T>) {
27349cc55cSDimitry Andric     uint32_t ID = OpPC.read<uint32_t>();
28349cc55cSDimitry Andric     return reinterpret_cast<T>(P.getNativePointer(ID));
29bdd1243dSDimitry Andric   } else {
30bdd1243dSDimitry Andric     return OpPC.read<T>();
31bdd1243dSDimitry Andric   }
32349cc55cSDimitry Andric }
33349cc55cSDimitry Andric 
ReadArg(Program & P,CodePtr & OpPC)34*5f757f3fSDimitry Andric template <> inline Floating ReadArg<Floating>(Program &P, CodePtr &OpPC) {
35*5f757f3fSDimitry Andric   Floating F = Floating::deserialize(*OpPC);
36*5f757f3fSDimitry Andric   OpPC += align(F.bytesToSerialize());
37*5f757f3fSDimitry Andric   return F;
38*5f757f3fSDimitry Andric }
39*5f757f3fSDimitry Andric 
dump() const40a7dea167SDimitry Andric LLVM_DUMP_METHOD void Function::dump() const { dump(llvm::errs()); }
41a7dea167SDimitry Andric 
dump(llvm::raw_ostream & OS) const42a7dea167SDimitry Andric LLVM_DUMP_METHOD void Function::dump(llvm::raw_ostream &OS) const {
4306c3fb27SDimitry Andric   OS << getName() << " " << (const void *)this << "\n";
44a7dea167SDimitry Andric   OS << "frame size: " << getFrameSize() << "\n";
45a7dea167SDimitry Andric   OS << "arg size:   " << getArgSize() << "\n";
46a7dea167SDimitry Andric   OS << "rvo:        " << hasRVO() << "\n";
47bdd1243dSDimitry Andric   OS << "this arg:   " << hasThisPointer() << "\n";
48a7dea167SDimitry Andric 
49a7dea167SDimitry Andric   auto PrintName = [&OS](const char *Name) {
50a7dea167SDimitry Andric     OS << Name;
5106c3fb27SDimitry Andric     long N = 30 - strlen(Name);
5206c3fb27SDimitry Andric     if (N > 0)
5306c3fb27SDimitry Andric       OS.indent(N);
54a7dea167SDimitry Andric   };
55a7dea167SDimitry Andric 
56a7dea167SDimitry Andric   for (CodePtr Start = getCodeBegin(), PC = Start; PC != getCodeEnd();) {
57a7dea167SDimitry Andric     size_t Addr = PC - Start;
58a7dea167SDimitry Andric     auto Op = PC.read<Opcode>();
59a7dea167SDimitry Andric     OS << llvm::format("%8d", Addr) << " ";
60a7dea167SDimitry Andric     switch (Op) {
61a7dea167SDimitry Andric #define GET_DISASM
62a7dea167SDimitry Andric #include "Opcodes.inc"
63a7dea167SDimitry Andric #undef GET_DISASM
64a7dea167SDimitry Andric     }
65a7dea167SDimitry Andric   }
66a7dea167SDimitry Andric }
67a7dea167SDimitry Andric 
dump() const68a7dea167SDimitry Andric LLVM_DUMP_METHOD void Program::dump() const { dump(llvm::errs()); }
69a7dea167SDimitry Andric 
dump(llvm::raw_ostream & OS) const70a7dea167SDimitry Andric LLVM_DUMP_METHOD void Program::dump(llvm::raw_ostream &OS) const {
71bdd1243dSDimitry Andric   OS << ":: Program\n";
72bdd1243dSDimitry Andric   OS << "Global Variables: " << Globals.size() << "\n";
73bdd1243dSDimitry Andric   OS << "Functions: " << Funcs.size() << "\n";
74bdd1243dSDimitry Andric   OS << "\n";
75a7dea167SDimitry Andric   for (auto &Func : Funcs) {
76a7dea167SDimitry Andric     Func.second->dump();
77a7dea167SDimitry Andric   }
78a7dea167SDimitry Andric   for (auto &Anon : AnonFuncs) {
79a7dea167SDimitry Andric     Anon->dump();
80a7dea167SDimitry Andric   }
81a7dea167SDimitry Andric }
82