// 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_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");

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 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 args;
  va_start(args, format);
  intptr_t len = Utils::VSNPrint(NULL, 0, format, args);
  va_end(args);
  char* p = reinterpret_cast<char*>(malloc(len + 1));
  va_start(args, format);
  intptr_t len2 = Utils::VSNPrint(p, len, format, args);
  va_end(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);
}

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 = 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 args;
  va_start(args, format);
  intptr_t len = Utils::VSNPrint(NULL, 0, format, args);
  va_end(args);
  if (remaining_ < len + 100) {
    *buffer_++ = '.';
    *buffer_++ = '.';
    *buffer_++ = '.';
    *buffer_++ = '\n';
    *buffer_++ = '\0';
    overflowed_ = true;
    return;
  }
  va_start(args, format);
  intptr_t len2 = Utils::VSNPrint(buffer_, len, format, args);
  va_end(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 Code::Comments* 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",
          String::Handle(comments->CommentAt(comment_finger)).ToCString());
      comment_finger++;
    }
    if (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) {
  Zone* zone = Thread::Current()->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 && FLAG_use_bare_instructions) {
    THR_Print("(No object pool for bare instructions.)\n");
  } 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)

  THR_Print("StackMaps for function '%s' {\n", function_fullname);
  if (code.compressed_stackmaps() != CompressedStackMaps::null()) {
    const auto& stackmaps =
        CompressedStackMaps::Handle(zone, code.compressed_stackmaps());
    THR_Print("%s\n", stackmaps.ToCString());
  }
  THR_Print("}\n");

  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);
      LocalVarDescriptorsLayout::VarInfo var_info;
      var_descriptors.GetInfo(i, &var_info);
      const int8_t kind = var_info.kind();
      if (kind == LocalVarDescriptorsLayout::kSavedCurrentContext) {
        THR_Print("  saved current CTX reg offset %d\n", var_info.index());
      } else {
        if (kind == LocalVarDescriptorsLayout::kContextLevel) {
          THR_Print("  context level %d scope %d", var_info.index(),
                    var_info.scope_id);
        } else if (kind == LocalVarDescriptorsLayout::kStackVar) {
          THR_Print("  stack var '%s' offset %d", var_name.ToCString(),
                    var_info.index());
        } else {
          ASSERT(kind == LocalVarDescriptorsLayout::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 (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).raw();
        } else if (object.IsCode()) {
          code = Code::Cast(object).raw();
        }

        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) {
  TextBuffer buffer(128);
  const char* function_fullname = function.ToFullyQualifiedCString();
  buffer.Printf("%s", Function::KindToCString(function.kind()));
  if (function.IsInvokeFieldDispatcher() ||
      function.IsNoSuchMethodDispatcher()) {
    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 && FLAG_use_bare_instructions) {
    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)

}  // namespace dart
