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

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 (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) {
    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)

  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
