// Copyright (c) 2019, 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/ffi_callback_trampolines.h"

#if !defined(DART_PRECOMPILED_RUNTIME)
#include "vm/code_comments.h"
#include "vm/code_observers.h"
#include "vm/compiler/assembler/assembler.h"
#include "vm/compiler/assembler/disassembler.h"
#include "vm/exceptions.h"
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

namespace dart {

DECLARE_FLAG(bool, disassemble_stubs);

#if !defined(DART_PRECOMPILED_RUNTIME)
uword NativeCallbackTrampolines::TrampolineForId(int32_t callback_id) {
#if defined(DART_PRECOMPILER)
  ASSERT(!Enabled());
  UNREACHABLE();
#else
  const intptr_t trampolines_per_page = NumCallbackTrampolinesPerPage();
  const intptr_t page_index = callback_id / trampolines_per_page;
  const uword entry_point = trampoline_pages_[page_index]->start();

  return entry_point +
         (callback_id % trampolines_per_page) *
             compiler::StubCodeCompiler::kNativeCallbackTrampolineSize;
#endif
}

void NativeCallbackTrampolines::AllocateTrampoline() {
#if defined(DART_PRECOMPILER)
  ASSERT(!Enabled());
  UNREACHABLE();
#else

  // Callback IDs are limited to 32-bits for trampoline compactness.
  if (kWordSize == 8 &&
      !Utils::IsInt(32, next_callback_id_ + NumCallbackTrampolinesPerPage())) {
    Exceptions::ThrowOOM();
  }

  if (trampolines_left_on_page_ == 0) {
    // Fuchsia requires memory to be allocated with ZX_RIGHT_EXECUTE in order
    // to be flipped to kReadExecute after being kReadWrite.
    VirtualMemory* const memory = VirtualMemory::AllocateAligned(
        /*size=*/VirtualMemory::PageSize(),
        /*alignment=*/VirtualMemory::PageSize(),
        /*is_executable=*/true, /*name=*/"Dart VM FFI callback trampolines");
    memory->Protect(VirtualMemory::kReadWrite);

    if (memory == nullptr) {
      Exceptions::ThrowOOM();
    }

    trampoline_pages_.Add(memory);

    compiler::Assembler assembler(/*object_pool_builder=*/nullptr);
    compiler::StubCodeCompiler::GenerateJITCallbackTrampolines(
        &assembler, next_callback_id_);

    MemoryRegion region(memory->address(), memory->size());
    assembler.FinalizeInstructions(region);

    memory->Protect(VirtualMemory::kReadExecute);

#if !defined(PRODUCT)
    const char* name = "FfiJitCallbackTrampolines";
    ASSERT(!Thread::Current()->IsAtSafepoint());
    if (CodeObservers::AreActive()) {
      const auto& comments = CreateCommentsFrom(&assembler);
      CodeObservers::NotifyAll(name,
                               /*base=*/memory->start(),
                               /*prologue_offset=*/0,
                               /*size=*/assembler.CodeSize(),
                               /*optimized=*/false,  // not really relevant
                               &comments);
    }
#endif
#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
    if (FLAG_disassemble_stubs && FLAG_support_disassembler) {
      DisassembleToStdout formatter;
      THR_Print(
          "Code for native callback trampolines "
          "[%" Pd " -> %" Pd "]: {\n",
          next_callback_id_,
          next_callback_id_ + NumCallbackTrampolinesPerPage() - 1);
      const auto& comments = CreateCommentsFrom(&assembler);
      Disassembler::Disassemble(memory->start(),
                                memory->start() + assembler.CodeSize(),
                                &formatter, &comments);
    }
#endif

    trampolines_left_on_page_ = NumCallbackTrampolinesPerPage();
  }

  trampolines_left_on_page_--;
  next_callback_id_++;
#endif  // defined(DART_PRECOMPILER)
}
#endif  // !defined(DART_PRECOMPILED_RUNTIME)

}  // namespace dart
