// 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.

#ifndef RUNTIME_VM_COMPILER_RUNTIME_API_H_
#define RUNTIME_VM_COMPILER_RUNTIME_API_H_

// This header defines the API that compiler can use to interact with the
// underlying Dart runtime that it is embedded into.
//
// Compiler is not allowed to directly interact with any objects - it can only
// use classes like dart::Object, dart::Code, dart::Function and similar as
// opaque handles. All interactions should be done through helper methods
// provided by this header.
//
// This header also provides ways to get word sizes, frame layout, field
// offsets for the target runtime. Note that these can be different from
// those on the host. Helpers providing access to these values live
// in compiler::target namespace.

#include "platform/globals.h"
#include "vm/allocation.h"
#include "vm/bitfield.h"
#include "vm/code_entry_kind.h"
#include "vm/frame_layout.h"
#include "vm/pointer_tagging.h"

namespace dart {

// Forward declarations.
class Class;
class Code;
class Function;
class LocalVariable;
class Object;
class RuntimeEntry;
class String;
class Zone;
namespace compiler {
class Assembler;
}

namespace compiler {

// Host word sizes.
//
// Code in the compiler namespace should not use kWordSize and derived
// constants directly because the word size on host and target might
// be different.
//
// To prevent this we introduce variables that would shadow these
// constants and introduce compilation errors when used.
//
// target::kWordSize and target::ObjectAlignment give access to
// word size and object aligment offsets for the target.
//
// Similarly kHostWordSize gives access to the host word size.
class InvalidClass {};
extern InvalidClass kWordSize;
extern InvalidClass kWordSizeLog2;
extern InvalidClass kNewObjectAlignmentOffset;
extern InvalidClass kOldObjectAlignmentOffset;
extern InvalidClass kNewObjectBitPosition;
extern InvalidClass kObjectAlignment;
extern InvalidClass kObjectAlignmentLog2;
extern InvalidClass kObjectAlignmentMask;

static constexpr intptr_t kHostWordSize = dart::kWordSize;
static constexpr intptr_t kHostWordSizeLog2 = dart::kWordSizeLog2;

//
// Object handles.
//

// Create an empty handle.
Object& NewZoneHandle(Zone* zone);

// Clone the given handle.
Object& NewZoneHandle(Zone* zone, const Object&);

// Returns true if [a] and [b] are the same object.
bool IsSameObject(const Object& a, const Object& b);

// Returns true if the given handle is a zone handle or one of the global
// cached handles.
bool IsNotTemporaryScopedHandle(const Object& obj);

// Returns true if [obj] resides in old space.
bool IsInOldSpace(const Object& obj);

// Returns true if [obj] is not a Field/ICData clone.
//
// Used to assert that we are not embedding pointers to cloned objects that are
// used by background compiler into object pools / code.
bool IsOriginalObject(const Object& object);

// Clear the given handle.
void SetToNull(Object* obj);

// Helper functions to upcast handles.
//
// Note: compiler code cannot include object.h so it cannot see that Object is
// a superclass of Code or Function - thus we have to cast these pointers using
// reinterpret_cast.
inline const Object& ToObject(const Code& handle) {
  return *reinterpret_cast<const Object*>(&handle);
}

inline const Object& ToObject(const Function& handle) {
  return *reinterpret_cast<const Object*>(&handle);
}

// Returns some hash value for the given object.
//
// Note: the given hash value does not necessarily match Object.get:hashCode,
// or canonical hash.
intptr_t ObjectHash(const Object& obj);

// If the given object represents a Dart integer returns true and sets [value]
// to the value of the integer.
bool HasIntegerValue(const dart::Object& obj, int64_t* value);

// Creates a random cookie to be used for masking constants embedded in the
// generated code.
int32_t CreateJitCookie();

typedef void (*RuntimeEntryCallInternal)(const dart::RuntimeEntry*,
                                         compiler::Assembler*,
                                         intptr_t);

class RuntimeEntry : public ValueObject {
 public:
  virtual ~RuntimeEntry() {}

  void Call(compiler::Assembler* assembler, intptr_t argument_count) const {
    ASSERT(call_ != NULL);
    ASSERT(runtime_entry_ != NULL);

    // We call a manually set function pointer which points to the
    // implementation of call for the subclass. We do this instead of just
    // defining Call in this class as a pure virtual method and providing an
    // implementation in the subclass as RuntimeEntry objects are declared as
    // globals which causes problems on Windows.
    //
    // When exit() is called on Windows, global objects start to be destroyed.
    // As part of an object's destruction, the vtable is reset to that of the
    // base class. Since some threads may still be running and accessing these
    // now destroyed globals, an invocation to dart::RuntimeEntry::Call would
    // instead invoke dart::compiler::RuntimeEntry::Call. If
    // dart::compiler::RuntimeEntry::Call were a pure virtual method, _purecall
    // would be invoked to handle the invalid call and attempt to call exit(),
    // causing the process to hang on a lock.
    //
    // By removing the need to rely on a potentially invalid vtable at exit,
    // we should be able to avoid hanging or crashing the process at shutdown,
    // even as global objects start to be destroyed. See issue #35855.
    call_(runtime_entry_, assembler, argument_count);
  }

 protected:
  RuntimeEntry(const dart::RuntimeEntry* runtime_entry,
               RuntimeEntryCallInternal call)
      : runtime_entry_(runtime_entry), call_(call) {}

 private:
  const dart::RuntimeEntry* runtime_entry_;
  RuntimeEntryCallInternal call_;
};

// Allocate a string object with the given content in the runtime heap.
const String& AllocateString(const char* buffer);

DART_NORETURN void BailoutWithBranchOffsetError();

// compiler::target namespace contains information about the target platform:
//
//    - word sizes and derived constants
//    - offsets of fields
//    - sizes of structures
namespace target {

// Currently we define target::word to match dart::word which represents
// host word.
//
// Once refactoring of the compiler is complete we will switch target::word
// to be independent from host word.
typedef dart::word word;
typedef dart::uword uword;

static constexpr word kWordSize = dart::kWordSize;
static constexpr word kWordSizeLog2 = dart::kWordSizeLog2;
static_assert((1 << kWordSizeLog2) == kWordSize,
              "kWordSizeLog2 should match kWordSize");

using ObjectAlignment = dart::ObjectAlignment<kWordSize, kWordSizeLog2>;

// Information about frame_layout that compiler should be targeting.
extern FrameLayout frame_layout;

// Returns the FP-relative index where [variable] can be found (assumes
// [variable] is not captured), in bytes.
inline int FrameOffsetInBytesForVariable(const LocalVariable* variable) {
  return frame_layout.FrameSlotForVariable(variable) * kWordSize;
}

// Encode tag word for a heap allocated object with the given class id and
// size.
//
// Note: even on 64-bit platforms we only use lower 32-bits of the tag word.
uint32_t MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size);

//
// Target specific information about objects.
//

// Returns true if the given object can be represented as a Smi on the
// target platform.
bool IsSmi(const dart::Object& a);

// Return raw Smi representation of the given object for the target platform.
word ToRawSmi(const dart::Object& a);

// Return raw Smi representation of the given integer value for the target
// platform.
//
// Note: method assumes that caller has validated that value is representable
// as a Smi.
word ToRawSmi(intptr_t value);

// If the given object can be loaded from the thread on the target then
// return true and set offset (if provided) to the offset from the
// thread pointer to a field that contains the object.
bool CanLoadFromThread(const dart::Object& object, word* offset = nullptr);

// On IA32 we can embed raw pointers into generated code.
#if defined(TARGET_ARCH_IA32)
// Returns true if the pointer to the given object can be directly embedded
// into the generated code (because the object is immortal and immovable).
bool CanEmbedAsRawPointerInGeneratedCode(const dart::Object& obj);

// Returns raw pointer value for the given object. Should only be invoked
// if CanEmbedAsRawPointerInGeneratedCode returns true.
word ToRawPointer(const dart::Object& a);
#endif  // defined(TARGET_ARCH_IA32)

//
// Target specific offsets and constants.
//
// Currently we use the same names for classes, constants and getters to make
// migration easier.

class RawObject : public AllStatic {
 public:
  static const word kClassIdTagPos;
  static const word kClassIdTagSize;
  static const word kBarrierOverlapShift;
};

class Object : public AllStatic {
 public:
  // Offset of the tags word.
  static word tags_offset();
};

class ObjectPool : public AllStatic {
 public:
  // Return offset to the element with the given [index] in the object pool.
  static intptr_t element_offset(intptr_t index);
};

class Class : public AllStatic {
 public:
  // Return class id of the given class on the target.
  static classid_t GetId(const dart::Class& handle);

  // Return instance size for the given class on the target.
  static uword GetInstanceSize(const dart::Class& handle);
};

class Instance : public AllStatic {
 public:
  static word DataOffsetFor(intptr_t cid);
};

class Double : public AllStatic {
 public:
  static word value_offset();
};

class Float32x4 : public AllStatic {
 public:
  static word value_offset();
};

class Float64x2 : public AllStatic {
 public:
  static word value_offset();
};

class Thread : public AllStatic {
 public:
  static word top_offset();
  static word end_offset();
  static word isolate_offset();
  static word call_to_runtime_entry_point_offset();
  static word null_error_shared_with_fpu_regs_entry_point_offset();
  static word null_error_shared_without_fpu_regs_entry_point_offset();
  static word write_barrier_mask_offset();
  static word monomorphic_miss_entry_offset();
  static word write_barrier_wrappers_thread_offset(intptr_t regno);
  static word array_write_barrier_entry_point_offset();
  static word write_barrier_entry_point_offset();
  static word vm_tag_offset();

#define THREAD_XMM_CONSTANT_LIST(V)                                            \
  V(float_not)                                                                 \
  V(float_negate)                                                              \
  V(float_absolute)                                                            \
  V(float_zerow)                                                               \
  V(double_negate)                                                             \
  V(double_abs)

#define DECLARE_CONSTANT_OFFSET_GETTER(name)                                   \
  static word name##_address_offset();
  THREAD_XMM_CONSTANT_LIST(DECLARE_CONSTANT_OFFSET_GETTER)
#undef DECLARE_CONSTANT_OFFSET_GETTER
};

class Isolate : public AllStatic {
 public:
  static word class_table_offset();
};

class ClassTable : public AllStatic {
 public:
  static word table_offset();
#if !defined(PRODUCT)
  static word ClassOffsetFor(intptr_t cid);
  static word StateOffsetFor(intptr_t cid);
  static word TableOffsetFor(intptr_t cid);
  static word CounterOffsetFor(intptr_t cid, bool is_new);
  static word SizeOffsetFor(intptr_t cid, bool is_new);
#endif  // !defined(PRODUCT)
  static const word kSizeOfClassPairLog2;
};

#if !defined(PRODUCT)
class ClassHeapStats : public AllStatic {
 public:
  static word TraceAllocationMask();
  static word state_offset();
  static word allocated_since_gc_new_space_offset();
  static word allocated_size_since_gc_new_space_offset();
};
#endif  // !defined(PRODUCT)

class Instructions : public AllStatic {
 public:
  static const intptr_t kPolymorphicEntryOffset;
  static const intptr_t kMonomorphicEntryOffset;
  static intptr_t HeaderSize();
};

class Code : public AllStatic {
 public:
#if defined(TARGET_ARCH_IA32)
  static uword EntryPointOf(const dart::Code& code);
#endif  // defined(TARGET_ARCH_IA32)

  static intptr_t object_pool_offset();
  static intptr_t entry_point_offset(
      CodeEntryKind kind = CodeEntryKind::kNormal);
  static intptr_t saved_instructions_offset();
};

class Heap : public AllStatic {
 public:
  // Return true if an object with the given instance size is allocatable
  // in new space on the target.
  static bool IsAllocatableInNewSpace(intptr_t instance_size);
};

}  // namespace target
}  // namespace compiler
}  // namespace dart

#endif  // RUNTIME_VM_COMPILER_RUNTIME_API_H_
