// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/compiler/assembler/disassembler.h"

#include "platform/text_buffer.h"
#include "platform/unaligned.h"
#include "vm/code_comments.h"
#include "vm/code_patcher.h"
#include "vm/dart_entry.h"
#include "vm/deopt_instructions.h"
#include "vm/globals.h"
#include "vm/instructions.h"
#include "vm/json_stream.h"
#include "vm/log.h"
#include "vm/os.h"

namespace dart {

#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)

#if !defined(DART_PRECOMPILED_RUNTIME)
DECLARE_FLAG(bool, trace_inlining_intervals);
#endif

DEFINE_FLAG(bool, trace_source_positions, false, "Source position diagnostics");
DEFINE_FLAG(bool,
            include_inlining_info_in_disassembly,
            true,
            "Include inlining information when printing disassembly")

void DisassembleToStdout::ConsumeInstruction(char* hex_buffer,
                                             intptr_t hex_size,
                                             char* human_buffer,
                                             intptr_t human_size,
                                             Object* object,
                                             uword pc) {
  static const int kHexColumnWidth = 23;
#if defined(TARGET_ARCH_IS_32_BIT)
  THR_Print("0x%" Px32 "    %s", static_cast<uint32_t>(pc), hex_buffer);
#else
  THR_Print("0x%" Px64 "    %s", static_cast<uint64_t>(pc), hex_buffer);
#endif
  int hex_length = strlen(hex_buffer);
  if (hex_length < kHexColumnWidth) {
    for (int i = kHexColumnWidth - hex_length; i > 0; i--) {
      THR_Print(" ");
    }
  }
  THR_Print("%s", human_buffer);
  if (object != NULL) {
    THR_Print("   %s", object->ToCString());
  }
  THR_Print("\n");
}

void DisassembleToStdout::Print(const char* format, ...) {
  va_list args;
  va_start(args, format);
  THR_VPrint(format, args);
  va_end(args);
}

void DisassembleToMemory::ConsumeInstruction(char* hex_buffer,
                                             intptr_t hex_size,
                                             char* human_buffer,
                                             intptr_t human_size,
                                             Object* object,
                                             uword pc) {
  if (overflowed_) {
    return;
  }
  intptr_t len;

  // TODO(compiler): Update assembler tests for other architectures so there is
  // coverage of encodings, not just mnemonics.
#if defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
  len = strlen(hex_buffer);
  if (remaining_ < len + 100) {
    *buffer_++ = '.';
    *buffer_++ = '.';
    *buffer_++ = '.';
    *buffer_++ = '\n';
    *buffer_++ = '\0';
    overflowed_ = true;
    return;
  }
  memmove(buffer_, hex_buffer, len);
  buffer_ += len;
  remaining_ -= len;
  *buffer_++ = ' ';
  remaining_--;
  *buffer_ = '\0';
#endif

  len = strlen(human_buffer);
  if (remaining_ < len + 100) {
    *buffer_++ = '.';
    *buffer_++ = '.';
    *buffer_++ = '.';
    *buffer_++ = '\n';
    *buffer_++ = '\0';
    overflowed_ = true;
    return;
  }
  memmove(buffer_, human_buffer, len);
  buffer_ += len;
  remaining_ -= len;
  *buffer_++ = '\n';
  remaining_--;
  *buffer_ = '\0';
}

void DisassembleToMemory::Print(const char* format, ...) {
  if (overflowed_) {
    return;
  }
  va_list measure_args;
  va_start(measure_args, format);
  intptr_t len = Utils::VSNPrint(NULL, 0, format, measure_args);
  va_end(measure_args);
  if (remaining_ < len + 100) {
    *buffer_++ = '.';
    *buffer_++ = '.';
    *buffer_++ = '.';
    *buffer_++ = '\n';
    *buffer_++ = '\0';
    overflowed_ = true;
    return;
  }
  va_list print_args;
  va_start(print_args, format);
  intptr_t len2 = Utils::VSNPrint(buffer_, len, format, print_args);
  va_end(print_args);
  ASSERT(len == len2);
  buffer_ += len;
  remaining_ -= len;
  *buffer_++ = '\n';
  remaining_--;
  *buffer_ = '\0';
}

void Disassembler::Disassemble(uword start,
                               uword end,
                               DisassemblyFormatter* formatter,
                               const Code& code,
                               const CodeComments* comments) {
  if (comments == nullptr) {
    comments = code.IsNull() ? &Code::Comments::New(0) : &code.comments();
  }
  ASSERT(formatter != NULL);
  char hex_buffer[kHexadecimalBufferSize];  // Instruction in hexadecimal form.
  char human_buffer[kUserReadableBufferSize];  // Human-readable instruction.
  uword pc = start;
  intptr_t comment_finger = 0;
  GrowableArray<const Function*> inlined_functions;
  GrowableArray<TokenPosition> token_positions;
  while (pc < end) {
    const intptr_t offset = pc - start;
    const intptr_t old_comment_finger = comment_finger;
    while (comment_finger < comments->Length() &&
           comments->PCOffsetAt(comment_finger) <= offset) {
      formatter->Print("        ;; %s\n", comments->CommentAt(comment_finger));
      comment_finger++;
    }
    if (FLAG_include_inlining_info_in_disassembly &&
        old_comment_finger != comment_finger && !code.IsNull()) {
      char str[4000];
      BufferFormatter f(str, sizeof(str));
      // Comment emitted, emit inlining information.
      code.GetInlinedFunctionsAtInstruction(offset, &inlined_functions,
                                            &token_positions);
      // Skip top scope function printing (last entry in 'inlined_functions').
      bool first = true;
      for (intptr_t i = 1; i < inlined_functions.length(); i++) {
        const char* name = inlined_functions[i]->ToQualifiedCString();
        if (first) {
          f.Printf("        ;; Inlined [%s", name);
          first = false;
        } else {
          f.Printf(" -> %s", name);
        }
      }
      if (!first) {
        f.AddString("]\n");
        formatter->Print("%s", str);
      }
    }
    int instruction_length;
    Object* object;
    DecodeInstruction(hex_buffer, sizeof(hex_buffer), human_buffer,
                      sizeof(human_buffer), &instruction_length, code, &object,
                      pc);
    formatter->ConsumeInstruction(hex_buffer, sizeof(hex_buffer), human_buffer,
                                  sizeof(human_buffer), object,
                                  FLAG_disassemble_relative ? offset : pc);
    pc += instruction_length;
  }
}

void Disassembler::DisassembleCodeHelper(const char* function_fullname,
                                         const char* function_info,
                                         const Code& code,
                                         bool optimized) {
  Thread* thread = Thread::Current();
  Zone* zone = thread->zone();
  LocalVarDescriptors& var_descriptors = LocalVarDescriptors::Handle(zone);
  if (FLAG_print_variable_descriptors) {
    var_descriptors = code.GetLocalVarDescriptors();
  }
  THR_Print("Code for %sfunction '%s' (%s) {\n", optimized ? "optimized " : "",
            function_fullname, function_info);
  code.Disassemble();
  THR_Print("}\n");

#if defined(TARGET_ARCH_IA32)
  THR_Print("Pointer offsets for function: {\n");
  // Pointer offsets are stored in descending order.
  Object& obj = Object::Handle(zone);
  for (intptr_t i = code.pointer_offsets_length() - 1; i >= 0; i--) {
    const uword addr = code.GetPointerOffsetAt(i) + code.PayloadStart();
    obj = LoadUnaligned(reinterpret_cast<ObjectPtr*>(addr));
    THR_Print(" %d : %#" Px " '%s'\n", code.GetPointerOffsetAt(i), addr,
              obj.ToCString());
  }
  THR_Print("}\n");
#else
  ASSERT(code.pointer_offsets_length() == 0);
#endif

  if (FLAG_precompiled_mode) {
    // Global object pool emitted after it is finalized instead of per-function.
  } else {
    const ObjectPool& object_pool =
        ObjectPool::Handle(zone, code.GetObjectPool());
    if (!object_pool.IsNull()) {
      object_pool.DebugPrint();
    }
  }

  code.DumpSourcePositions(/*relative_addresses=*/FLAG_disassemble_relative);

  THR_Print("PC Descriptors for function '%s' {\n", function_fullname);
  PcDescriptors::PrintHeaderString();
  const PcDescriptors& descriptors =
      PcDescriptors::Handle(zone, code.pc_descriptors());
  THR_Print("%s}\n", descriptors.ToCString());

  const uword start = code.PayloadStart();
  const uword base = FLAG_disassemble_relative ? 0 : start;

#if !defined(DART_PRECOMPILED_RUNTIME)
  const Array& deopt_table = Array::Handle(zone, code.deopt_info_array());
  if (!deopt_table.IsNull()) {
    intptr_t deopt_table_length = DeoptTable::GetLength(deopt_table);
    if (deopt_table_length > 0) {
      THR_Print("DeoptInfo: {\n");
      Smi& offset = Smi::Handle(zone);
      TypedData& info = TypedData::Handle(zone);
      Smi& reason_and_flags = Smi::Handle(zone);
      for (intptr_t i = 0; i < deopt_table_length; ++i) {
        DeoptTable::GetEntry(deopt_table, i, &offset, &info, &reason_and_flags);
        const intptr_t reason =
            DeoptTable::ReasonField::decode(reason_and_flags.Value());
        ASSERT((0 <= reason) && (reason < ICData::kDeoptNumReasons));
        THR_Print(
            "%4" Pd ": 0x%" Px "  %s  (%s)\n", i, base + offset.Value(),
            DeoptInfo::ToCString(deopt_table, info),
            DeoptReasonToCString(static_cast<ICData::DeoptReasonId>(reason)));
      }
      THR_Print("}\n");
    }
  }
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

  const auto& stackmaps =
      CompressedStackMaps::Handle(zone, code.compressed_stackmaps());
  if (!stackmaps.IsNull()) {
    TextBuffer buffer(100);
    buffer.Printf("StackMaps for function '%s' {\n", function_fullname);
    stackmaps.WriteToBuffer(&buffer, "\n");
    buffer.AddString("}\n");
    THR_Print("%s", buffer.buffer());
  }

  if (FLAG_print_variable_descriptors) {
    THR_Print("Variable Descriptors for function '%s' {\n", function_fullname);
    intptr_t var_desc_length =
        var_descriptors.IsNull() ? 0 : var_descriptors.Length();
    String& var_name = String::Handle(zone);
    for (intptr_t i = 0; i < var_desc_length; i++) {
      var_name = var_descriptors.GetName(i);
      UntaggedLocalVarDescriptors::VarInfo var_info;
      var_descriptors.GetInfo(i, &var_info);
      const int8_t kind = var_info.kind();
      if (kind == UntaggedLocalVarDescriptors::kSavedCurrentContext) {
        THR_Print("  saved current CTX reg offset %d\n", var_info.index());
      } else {
        if (kind == UntaggedLocalVarDescriptors::kContextLevel) {
          THR_Print("  context level %d scope %d", var_info.index(),
                    var_info.scope_id);
        } else if (kind == UntaggedLocalVarDescriptors::kStackVar) {
          THR_Print("  stack var '%s' offset %d", var_name.ToCString(),
                    var_info.index());
        } else {
          ASSERT(kind == UntaggedLocalVarDescriptors::kContextVar);
          THR_Print("  context var '%s' level %d offset %d",
                    var_name.ToCString(), var_info.scope_id, var_info.index());
        }
        THR_Print(" (valid %s-%s)\n", var_info.begin_pos.ToCString(),
                  var_info.end_pos.ToCString());
      }
    }
    THR_Print("}\n");
  }

  THR_Print("Exception Handlers for function '%s' {\n", function_fullname);
  const ExceptionHandlers& handlers =
      ExceptionHandlers::Handle(zone, code.exception_handlers());
  THR_Print("%s}\n", handlers.ToCString());

#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)
  if (FLAG_precompiled_mode &&
      code.catch_entry_moves_maps() != Object::null()) {
    THR_Print("Catch entry moves for function '%s' {\n", function_fullname);
    CatchEntryMovesMapReader reader(
        TypedData::Handle(code.catch_entry_moves_maps()));
    reader.PrintEntries();
    THR_Print("}\n");
  }
#endif  // defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER)

  {
    THR_Print("Entry points for function '%s' {\n", function_fullname);
    THR_Print("  [code+0x%02" Px "] %" Px " kNormal\n",
              Code::entry_point_offset(CodeEntryKind::kNormal) - kHeapObjectTag,
              code.EntryPoint() - start + base);
    THR_Print(
        "  [code+0x%02" Px "] %" Px " kMonomorphic\n",
        Code::entry_point_offset(CodeEntryKind::kMonomorphic) - kHeapObjectTag,
        code.MonomorphicEntryPoint() - start + base);
    THR_Print(
        "  [code+0x%02" Px "] %" Px " kUnchecked\n",
        Code::entry_point_offset(CodeEntryKind::kUnchecked) - kHeapObjectTag,
        code.UncheckedEntryPoint() - start + base);
    THR_Print("  [code+0x%02" Px "] %" Px " kMonomorphicUnchecked\n",
              Code::entry_point_offset(CodeEntryKind::kMonomorphicUnchecked) -
                  kHeapObjectTag,
              code.MonomorphicUncheckedEntryPoint() - start + base);
    THR_Print("}\n");
  }

#if defined(DART_PRECOMPILED_RUNTIME)
  THR_Print("(Cannot show static call target functions in AOT runtime.)\n");
#else
  {
    THR_Print("Static call target functions {\n");
    const auto& table = Array::Handle(zone, code.static_calls_target_table());
    auto& cls = Class::Handle(zone);
    auto& kind_type_and_offset = Smi::Handle(zone);
    auto& function = Function::Handle(zone);
    auto& object = Object::Handle(zone);
    auto& code = Code::Handle(zone);
    auto& dst_type = AbstractType::Handle(zone);
    if (!table.IsNull()) {
      StaticCallsTable static_calls(table);
      for (auto& call : static_calls) {
        kind_type_and_offset = call.Get<Code::kSCallTableKindAndOffset>();
        function = call.Get<Code::kSCallTableFunctionTarget>();
        object = call.Get<Code::kSCallTableCodeOrTypeTarget>();

        dst_type = AbstractType::null();
        if (object.IsAbstractType()) {
          dst_type = AbstractType::Cast(object).ptr();
        } else if (object.IsCode()) {
          code = Code::Cast(object).ptr();
        }

        auto kind = Code::KindField::decode(kind_type_and_offset.Value());
        auto offset = Code::OffsetField::decode(kind_type_and_offset.Value());
        auto entry_point =
            Code::EntryPointField::decode(kind_type_and_offset.Value());

        const char* s_entry_point =
            entry_point == Code::kUncheckedEntry ? " <unchecked-entry>" : "";
        const char* skind = nullptr;
        switch (kind) {
          case Code::kPcRelativeCall:
            skind = "pc-relative-call";
            break;
          case Code::kPcRelativeTTSCall:
            skind = "pc-relative-tts-call";
            break;
          case Code::kPcRelativeTailCall:
            skind = "pc-relative-tail-call";
            break;
          case Code::kCallViaCode:
            skind = "call-via-code";
            break;
          default:
            UNREACHABLE();
        }
        if (!dst_type.IsNull()) {
          THR_Print("  0x%" Px ": type testing stub %s, (%s)%s\n",
                    base + offset, dst_type.ToCString(), skind, s_entry_point);
        } else if (function.IsNull()) {
          cls ^= code.owner();
          if (cls.IsNull()) {
            THR_Print(
                "  0x%" Px ": %s, (%s)%s\n", base + offset,
                code.QualifiedName(NameFormattingParams(
                    Object::kScrubbedName, Object::NameDisambiguation::kYes)),
                skind, s_entry_point);
          } else {
            THR_Print("  0x%" Px ": allocation stub for %s, (%s)%s\n",
                      base + offset, cls.ToCString(), skind, s_entry_point);
          }
        } else {
          THR_Print("  0x%" Px ": %s, (%s)%s\n", base + offset,
                    function.ToFullyQualifiedCString(), skind, s_entry_point);
        }
      }
    }
    THR_Print("}\n");
  }
#endif  // defined(DART_PRECOMPILED_RUNTIME)

#if !defined(DART_PRECOMPILED_RUNTIME)
  if (optimized && FLAG_trace_inlining_intervals) {
    code.DumpInlineIntervals();
  }
#endif

  if (FLAG_trace_source_positions) {
    code.DumpSourcePositions();
  }
}

void Disassembler::DisassembleCode(const Function& function,
                                   const Code& code,
                                   bool optimized) {
  if (code.IsUnknownDartCode()) {
    return;
  }
  TextBuffer buffer(128);
  const char* function_fullname = function.ToFullyQualifiedCString();
  buffer.Printf("%s", Function::KindToCString(function.kind()));
  if (function.HasSavedArgumentsDescriptor()) {
    const auto& args_desc_array = Array::Handle(function.saved_args_desc());
    const ArgumentsDescriptor args_desc(args_desc_array);
    buffer.AddString(", ");
    args_desc.PrintTo(&buffer);
  }
  LogBlock lb;
  DisassembleCodeHelper(function_fullname, buffer.buffer(), code, optimized);
}

void Disassembler::DisassembleStub(const char* name, const Code& code) {
  LogBlock lb;
  THR_Print("Code for stub '%s': {\n", name);
  DisassembleToStdout formatter;
  code.Disassemble(&formatter);
  THR_Print("}\n");
  const ObjectPool& object_pool = ObjectPool::Handle(code.object_pool());
  if (FLAG_precompiled_mode) {
    THR_Print("(No object pool for bare instructions.)\n");
  } else if (!object_pool.IsNull()) {
    object_pool.DebugPrint();
  }
}

#else   // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)

void Disassembler::DisassembleCode(const Function& function,
                                   const Code& code,
                                   bool optimized) {}
#endif  // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)

#if !defined(PRODUCT)
void DisassembleToJSONStream::ConsumeInstruction(char* hex_buffer,
                                                 intptr_t hex_size,
                                                 char* human_buffer,
                                                 intptr_t human_size,
                                                 Object* object,
                                                 uword pc) {
  // Instructions are represented as four consecutive values in a JSON array.
  // The first is the address of the instruction, the second is the hex string,
  // of the code, and the third is a human readable string, and the fourth is
  // the object loaded by the instruction.
  jsarr_.AddValueF("%" Pp "", pc);
  jsarr_.AddValue(hex_buffer);
  jsarr_.AddValue(human_buffer);

  if (object != NULL) {
    jsarr_.AddValue(*object);
  } else {
    jsarr_.AddValueNull();  // Not a reference to null.
  }
}

void DisassembleToJSONStream::Print(const char* format, ...) {
  va_list measure_args;
  va_start(measure_args, format);
  intptr_t len = Utils::VSNPrint(NULL, 0, format, measure_args);
  va_end(measure_args);

  char* p = reinterpret_cast<char*>(malloc(len + 1));
  va_list print_args;
  va_start(print_args, format);
  intptr_t len2 = Utils::VSNPrint(p, len, format, print_args);
  va_end(print_args);
  ASSERT(len == len2);
  for (intptr_t i = 0; i < len; i++) {
    if (p[i] == '\n' || p[i] == '\r') {
      p[i] = ' ';
    }
  }
  // Instructions are represented as four consecutive values in a JSON array.
  // Comments only use the third slot. See above comment for more information.
  jsarr_.AddValueNull();
  jsarr_.AddValueNull();
  jsarr_.AddValue(p);
  jsarr_.AddValueNull();
  free(p);
}
#endif  // !defined(PRODUCT)

}  // namespace dart
