// 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/compiler/runtime_api.h"

#if !defined(DART_PRECOMPILED_RUNTIME)

#include "vm/dart_entry.h"
#include "vm/longjump.h"
#include "vm/native_arguments.h"
#include "vm/native_entry.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/runtime_entry.h"
#include "vm/symbols.h"
#include "vm/timeline.h"

namespace dart {
namespace compiler {

bool IsSameObject(const Object& a, const Object& b) {
  return a.raw() == b.raw();
}

bool IsEqualType(const AbstractType& a, const AbstractType& b) {
  return a.Equals(b);
}

bool IsDoubleType(const AbstractType& type) {
  return type.IsDoubleType();
}

bool IsIntType(const AbstractType& type) {
  return type.IsIntType();
}

bool IsSmiType(const AbstractType& type) {
  return type.IsSmiType();
}

bool IsNotTemporaryScopedHandle(const Object& obj) {
  return obj.IsNotTemporaryScopedHandle();
}

#define DO(clazz)                                                              \
  bool Is##clazz##Handle(const Object& obj) { return obj.Is##clazz(); }
CLASS_LIST_FOR_HANDLES(DO)
#undef DO

bool IsInOldSpace(const Object& obj) {
  return obj.IsOld();
}

intptr_t ObjectHash(const Object& obj) {
  if (obj.IsNull()) {
    return 2011;
  }
  if (obj.IsString() || obj.IsNumber()) {
    return Instance::Cast(obj).CanonicalizeHash();
  }
  if (obj.IsCode()) {
    // Instructions don't move during compaction.
    return Code::Cast(obj).PayloadStart();
  }
  if (obj.IsFunction()) {
    return Function::Cast(obj).Hash();
  }
  if (obj.IsField()) {
    return dart::String::HashRawSymbol(Field::Cast(obj).name());
  }
  // Unlikely.
  return obj.GetClassId();
}

void SetToNull(Object* obj) {
  *obj = Object::null();
}

Object& NewZoneHandle(Zone* zone) {
  return Object::ZoneHandle(zone, Object::null());
}

Object& NewZoneHandle(Zone* zone, const Object& obj) {
  return Object::ZoneHandle(zone, obj.raw());
}

const Object& NullObject() {
  return Object::null_object();
}

const Bool& TrueObject() {
  return dart::Bool::True();
}

const Bool& FalseObject() {
  return dart::Bool::False();
}

const Object& EmptyTypeArguments() {
  return Object::empty_type_arguments();
}

const Type& DynamicType() {
  return dart::Type::dynamic_type();
}

const Type& ObjectType() {
  return Type::Handle(dart::Type::ObjectType());
}

const Type& VoidType() {
  return dart::Type::void_type();
}

const Type& IntType() {
  return Type::Handle(dart::Type::IntType());
}

const Class& GrowableObjectArrayClass() {
  auto object_store = Isolate::Current()->object_store();
  return Class::Handle(object_store->growable_object_array_class());
}

const Class& MintClass() {
  auto object_store = Isolate::Current()->object_store();
  return Class::Handle(object_store->mint_class());
}

const Class& DoubleClass() {
  auto object_store = Isolate::Current()->object_store();
  return Class::Handle(object_store->double_class());
}

bool IsOriginalObject(const Object& object) {
  if (object.IsICData()) {
    return ICData::Cast(object).IsOriginal();
  } else if (object.IsField()) {
    return Field::Cast(object).IsOriginal();
  }
  return true;
}

const String& AllocateString(const char* buffer) {
  return String::ZoneHandle(String::New(buffer, dart::Heap::kOld));
}

bool HasIntegerValue(const dart::Object& object, int64_t* value) {
  if (object.IsInteger()) {
    *value = Integer::Cast(object).AsInt64Value();
    return true;
  }
  return false;
}

int32_t CreateJitCookie() {
  return static_cast<int32_t>(Isolate::Current()->random()->NextUInt32());
}

word TypedDataElementSizeInBytes(classid_t cid) {
  return dart::TypedData::ElementSizeInBytes(cid);
}

word TypedDataMaxNewSpaceElements(classid_t cid) {
  return dart::TypedData::MaxNewSpaceElements(cid);
}

const Field& LookupMathRandomStateFieldOffset() {
  const auto& math_lib = dart::Library::Handle(dart::Library::MathLibrary());
  ASSERT(!math_lib.IsNull());
  const auto& random_class = dart::Class::Handle(
      math_lib.LookupClassAllowPrivate(dart::Symbols::_Random()));
  ASSERT(!random_class.IsNull());
  const auto& state_field = dart::Field::ZoneHandle(
      random_class.LookupInstanceFieldAllowPrivate(dart::Symbols::_state()));
  return state_field;
}

word LookupFieldOffsetInBytes(const Field& field) {
  return field.Offset();
}

#if defined(TARGET_ARCH_IA32)
uword SymbolsPredefinedAddress() {
  return reinterpret_cast<uword>(dart::Symbols::PredefinedAddress());
}
#endif

#if !defined(TARGET_ARCH_DBC)
const Code& StubCodeAllocateArray() {
  return dart::StubCode::AllocateArray();
}

const Code& StubCodeSubtype2TestCache() {
  return dart::StubCode::Subtype2TestCache();
}

const Code& StubCodeSubtype6TestCache() {
  return dart::StubCode::Subtype6TestCache();
}
#endif  // !defined(TARGET_ARCH_DBC)

#define DEFINE_ALIAS(name)                                                     \
  const RuntimeEntry& k##name##RuntimeEntry(dart::k##name##RuntimeEntry);
RUNTIME_ENTRY_LIST(DEFINE_ALIAS)
#undef DEFINE_ALIAS

#define DEFINE_ALIAS(type, name, ...)                                          \
  const RuntimeEntry& k##name##RuntimeEntry(dart::k##name##RuntimeEntry);
LEAF_RUNTIME_ENTRY_LIST(DEFINE_ALIAS)
#undef DEFINE_ALIAS

void BailoutWithBranchOffsetError() {
  Thread::Current()->long_jump_base()->Jump(1, Object::branch_offset_error());
}

word RuntimeEntry::OffsetFromThread() const {
  return dart::Thread::OffsetFromThread(runtime_entry_);
}

namespace target {

const word kPageSize = dart::kPageSize;
const word kPageSizeInWords = dart::kPageSizeInWords;
const word kPageMask = dart::kPageMask;

uint32_t MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size) {
  return dart::RawObject::SizeTag::encode(instance_size) |
         dart::RawObject::ClassIdTag::encode(cid) |
         dart::RawObject::NewBit::encode(true);
}

word Object::tags_offset() {
  return dart::Object::tags_offset();
}

const word RawObject::kCardRememberedBit = dart::RawObject::kCardRememberedBit;

const word RawObject::kOldAndNotRememberedBit =
    dart::RawObject::kOldAndNotRememberedBit;

const word RawObject::kOldAndNotMarkedBit =
    dart::RawObject::kOldAndNotMarkedBit;

const word RawObject::kClassIdTagPos = dart::RawObject::kClassIdTagPos;

const word RawObject::kClassIdTagSize = dart::RawObject::kClassIdTagSize;

const word RawObject::kSizeTagMaxSizeTag =
    dart::RawObject::SizeTag::kMaxSizeTag;

const word RawObject::kTagBitsSizeTagPos =
    dart::RawObject::TagBits::kSizeTagPos;

const word RawAbstractType::kTypeStateFinalizedInstantiated =
    dart::RawAbstractType::kFinalizedInstantiated;

const word RawObject::kBarrierOverlapShift =
    dart::RawObject::kBarrierOverlapShift;

bool RawObject::IsTypedDataClassId(intptr_t cid) {
  return dart::RawObject::IsTypedDataClassId(cid);
}

intptr_t ObjectPool::element_offset(intptr_t index) {
  return dart::ObjectPool::element_offset(index);
}

word Class::type_arguments_field_offset_in_words_offset() {
  return dart::Class::type_arguments_field_offset_in_words_offset();
}

word Class::declaration_type_offset() {
  return dart::Class::declaration_type_offset();
}

word Class::num_type_arguments_offset_in_bytes() {
  return dart::Class::num_type_arguments_offset();
}

const word Class::kNoTypeArguments = dart::Class::kNoTypeArguments;

classid_t Class::GetId(const dart::Class& handle) {
  return handle.id();
}

uword Class::GetInstanceSize(const dart::Class& handle) {
  return handle.instance_size();
}

intptr_t Class::NumTypeArguments(const dart::Class& klass) {
  return klass.NumTypeArguments() > 0;
}

bool Class::HasTypeArgumentsField(const dart::Class& klass) {
  return klass.type_arguments_field_offset() != dart::Class::kNoTypeArguments;
}

intptr_t Class::TypeArgumentsFieldOffset(const dart::Class& klass) {
  return klass.type_arguments_field_offset();
}

intptr_t Class::InstanceSize(const dart::Class& klass) {
  return klass.instance_size();
}

bool Class::TraceAllocation(const dart::Class& klass) {
  return klass.TraceAllocation(dart::Isolate::Current());
}

word Instance::first_field_offset() {
  return dart::Instance::NextFieldOffset();
}

word Instance::DataOffsetFor(intptr_t cid) {
  return dart::Instance::DataOffsetFor(cid);
}

word Instance::ElementSizeFor(intptr_t cid) {
  return dart::Instance::ElementSizeFor(cid);
}

word Function::code_offset() {
  return dart::Function::code_offset();
}

word Function::entry_point_offset() {
  return dart::Function::entry_point_offset();
}

word Function::usage_counter_offset() {
  return dart::Function::usage_counter_offset();
}

word Function::unchecked_entry_point_offset() {
  return dart::Function::unchecked_entry_point_offset();
}

word ICData::CodeIndexFor(word num_args) {
  return dart::ICData::CodeIndexFor(num_args);
}

word ICData::owner_offset() {
  return dart::ICData::owner_offset();
}

word ICData::arguments_descriptor_offset() {
  return dart::ICData::arguments_descriptor_offset();
}

word ICData::entries_offset() {
  return dart::ICData::entries_offset();
}

word ICData::receivers_static_type_offset() {
  return dart::ICData::receivers_static_type_offset();
}

word ICData::state_bits_offset() {
  return dart::ICData::state_bits_offset();
}

word ICData::CountIndexFor(word num_args) {
  return dart::ICData::CountIndexFor(num_args);
}

word ICData::TargetIndexFor(word num_args) {
  return dart::ICData::TargetIndexFor(num_args);
}

word ICData::ExactnessIndexFor(word num_args) {
  return dart::ICData::ExactnessIndexFor(num_args);
}

word ICData::TestEntryLengthFor(word num_args, bool exactness_check) {
  return dart::ICData::TestEntryLengthFor(num_args, exactness_check);
}

word ICData::EntryPointIndexFor(word num_args) {
  return dart::ICData::EntryPointIndexFor(num_args);
}

word ICData::NumArgsTestedShift() {
  return dart::ICData::NumArgsTestedShift();
}

word ICData::NumArgsTestedMask() {
  return dart::ICData::NumArgsTestedMask();
}

const word MegamorphicCache::kSpreadFactor =
    dart::MegamorphicCache::kSpreadFactor;

word MegamorphicCache::mask_offset() {
  return dart::MegamorphicCache::mask_offset();
}
word MegamorphicCache::buckets_offset() {
  return dart::MegamorphicCache::buckets_offset();
}
word MegamorphicCache::arguments_descriptor_offset() {
  return dart::MegamorphicCache::arguments_descriptor_offset();
}

word SingleTargetCache::lower_limit_offset() {
  return dart::SingleTargetCache::lower_limit_offset();
}
word SingleTargetCache::upper_limit_offset() {
  return dart::SingleTargetCache::upper_limit_offset();
}
word SingleTargetCache::entry_point_offset() {
  return dart::SingleTargetCache::entry_point_offset();
}
word SingleTargetCache::target_offset() {
  return dart::SingleTargetCache::target_offset();
}

const word Array::kMaxNewSpaceElements = dart::Array::kMaxNewSpaceElements;

word Context::InstanceSize(word n) {
  return dart::Context::InstanceSize(n);
}

word Context::variable_offset(word n) {
  return dart::Context::variable_offset(n);
}

word TypedData::InstanceSize() {
  return sizeof(RawTypedData);
}

word Array::header_size() {
  return sizeof(dart::RawArray);
}

#define CLASS_NAME_LIST(V)                                                     \
  V(AbstractType, type_test_stub_entry_point_offset)                           \
  V(ArgumentsDescriptor, count_offset)                                         \
  V(ArgumentsDescriptor, type_args_len_offset)                                 \
  V(Array, data_offset)                                                        \
  V(Array, length_offset)                                                      \
  V(Array, tags_offset)                                                        \
  V(Array, type_arguments_offset)                                              \
  V(ClassTable, table_offset)                                                  \
  V(Closure, context_offset)                                                   \
  V(Closure, delayed_type_arguments_offset)                                    \
  V(Closure, function_offset)                                                  \
  V(Closure, function_type_arguments_offset)                                   \
  V(Closure, instantiator_type_arguments_offset)                               \
  V(Code, object_pool_offset)                                                  \
  V(Code, saved_instructions_offset)                                           \
  V(Context, num_variables_offset)                                             \
  V(Context, parent_offset)                                                    \
  V(Double, value_offset)                                                      \
  V(Float32x4, value_offset)                                                   \
  V(Float64x2, value_offset)                                                   \
  V(GrowableObjectArray, data_offset)                                          \
  V(GrowableObjectArray, length_offset)                                        \
  V(GrowableObjectArray, type_arguments_offset)                                \
  V(HeapPage, card_table_offset)                                               \
  V(Isolate, class_table_offset)                                               \
  V(Isolate, current_tag_offset)                                               \
  V(Isolate, default_tag_offset)                                               \
  V(Isolate, ic_miss_code_offset)                                              \
  V(Isolate, object_store_offset)                                              \
  V(Isolate, user_tag_offset)                                                  \
  V(MarkingStackBlock, pointers_offset)                                        \
  V(MarkingStackBlock, top_offset)                                             \
  V(Mint, value_offset)                                                        \
  V(NativeArguments, argc_tag_offset)                                          \
  V(NativeArguments, argv_offset)                                              \
  V(NativeArguments, retval_offset)                                            \
  V(NativeArguments, thread_offset)                                            \
  V(ObjectStore, double_type_offset)                                           \
  V(ObjectStore, int_type_offset)                                              \
  V(ObjectStore, string_type_offset)                                           \
  V(OneByteString, data_offset)                                                \
  V(StoreBufferBlock, pointers_offset)                                         \
  V(StoreBufferBlock, top_offset)                                              \
  V(String, hash_offset)                                                       \
  V(String, length_offset)                                                     \
  V(SubtypeTestCache, cache_offset)                                            \
  V(Thread, active_exception_offset)                                           \
  V(Thread, active_stacktrace_offset)                                          \
  V(Thread, async_stack_trace_offset)                                          \
  V(Thread, auto_scope_native_wrapper_entry_point_offset)                      \
  V(Thread, bool_false_offset)                                                 \
  V(Thread, bool_true_offset)                                                  \
  V(Thread, dart_stream_offset)                                                \
  V(Thread, end_offset)                                                        \
  V(Thread, global_object_pool_offset)                                         \
  V(Thread, isolate_offset)                                                    \
  V(Thread, marking_stack_block_offset)                                        \
  V(Thread, no_scope_native_wrapper_entry_point_offset)                        \
  V(Thread, object_null_offset)                                                \
  V(Thread, predefined_symbols_address_offset)                                 \
  V(Thread, resume_pc_offset)                                                  \
  V(Thread, store_buffer_block_offset)                                         \
  V(Thread, top_exit_frame_info_offset)                                        \
  V(Thread, top_offset)                                                        \
  V(Thread, top_resource_offset)                                               \
  V(Thread, vm_tag_offset)                                                     \
  V(Thread, safepoint_state_offset)                                            \
  V(Thread, callback_code_offset)                                              \
  V(TimelineStream, enabled_offset)                                            \
  V(TwoByteString, data_offset)                                                \
  V(Type, arguments_offset)                                                    \
  V(TypedDataBase, data_field_offset)                                          \
  V(TypedDataBase, length_offset)                                              \
  V(TypedData, data_offset)                                                    \
  V(Type, hash_offset)                                                         \
  V(TypeRef, type_offset)                                                      \
  V(Type, signature_offset)                                                    \
  V(Type, type_state_offset)                                                   \
  V(UserTag, tag_offset)

#define DEFINE_FORWARDER(clazz, name)                                          \
  word clazz::name() { return dart::clazz::name(); }

CLASS_NAME_LIST(DEFINE_FORWARDER)
#undef DEFINE_FORWARDER

uword Thread::safepoint_state_unacquired() {
  return dart::Thread::safepoint_state_unacquired();
}

uword Thread::safepoint_state_acquired() {
  return dart::Thread::safepoint_state_acquired();
}

const word HeapPage::kBytesPerCardLog2 = dart::HeapPage::kBytesPerCardLog2;

const word String::kHashBits = dart::String::kHashBits;

word String::InstanceSize() {
  return sizeof(dart::RawString);
}

bool Heap::IsAllocatableInNewSpace(intptr_t instance_size) {
  return dart::Heap::IsAllocatableInNewSpace(instance_size);
}

#if !defined(TARGET_ARCH_DBC)
word Thread::write_barrier_code_offset() {
  return dart::Thread::write_barrier_code_offset();
}

word Thread::array_write_barrier_code_offset() {
  return dart::Thread::array_write_barrier_code_offset();
}

word Thread::fix_callers_target_code_offset() {
  return dart::Thread::fix_callers_target_code_offset();
}

word Thread::fix_allocation_stub_code_offset() {
  return dart::Thread::fix_allocation_stub_code_offset();
}

word Thread::call_to_runtime_entry_point_offset() {
  return dart::Thread::call_to_runtime_entry_point_offset();
}

word Thread::null_error_shared_with_fpu_regs_entry_point_offset() {
  return dart::Thread::null_error_shared_with_fpu_regs_entry_point_offset();
}

word Thread::null_error_shared_without_fpu_regs_entry_point_offset() {
  return dart::Thread::null_error_shared_without_fpu_regs_entry_point_offset();
}

word Thread::monomorphic_miss_entry_offset() {
  return dart::Thread::monomorphic_miss_entry_offset();
}

word Thread::write_barrier_mask_offset() {
  return dart::Thread::write_barrier_mask_offset();
}

word Thread::write_barrier_entry_point_offset() {
  return dart::Thread::write_barrier_entry_point_offset();
}

word Thread::array_write_barrier_entry_point_offset() {
  return dart::Thread::array_write_barrier_entry_point_offset();
}

word Thread::verify_callback_isolate_entry_point_offset() {
  return dart::Thread::verify_callback_entry_offset();
}
#endif  // !defined(TARGET_ARCH_DBC)

#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_ARM64) ||                  \
    defined(TARGET_ARCH_X64)
word Thread::write_barrier_wrappers_thread_offset(intptr_t regno) {
  return dart::Thread::write_barrier_wrappers_thread_offset(
      static_cast<Register>(regno));
}
#endif

#if !defined(TARGET_ARCH_DBC)

word Thread::monomorphic_miss_stub_offset() {
  return dart::Thread::monomorphic_miss_stub_offset();
}

word Thread::ic_lookup_through_code_stub_offset() {
  return dart::Thread::ic_lookup_through_code_stub_offset();
}

word Thread::lazy_specialize_type_test_stub_offset() {
  return dart::Thread::lazy_specialize_type_test_stub_offset();
}

word Thread::slow_type_test_stub_offset() {
  return dart::Thread::slow_type_test_stub_offset();
}

word Thread::call_to_runtime_stub_offset() {
  return dart::Thread::call_to_runtime_stub_offset();
}

word Thread::invoke_dart_code_stub_offset() {
  return dart::Thread::invoke_dart_code_stub_offset();
}

word Thread::interpret_call_entry_point_offset() {
  return dart::Thread::interpret_call_entry_point_offset();
}

word Thread::invoke_dart_code_from_bytecode_stub_offset() {
  return dart::Thread::invoke_dart_code_from_bytecode_stub_offset();
}

word Thread::null_error_shared_without_fpu_regs_stub_offset() {
  return dart::Thread::null_error_shared_without_fpu_regs_stub_offset();
}

word Thread::null_error_shared_with_fpu_regs_stub_offset() {
  return dart::Thread::null_error_shared_with_fpu_regs_stub_offset();
}

word Thread::stack_overflow_shared_without_fpu_regs_stub_offset() {
  return dart::Thread::stack_overflow_shared_without_fpu_regs_stub_offset();
}

word Thread::stack_overflow_shared_with_fpu_regs_stub_offset() {
  return dart::Thread::stack_overflow_shared_with_fpu_regs_stub_offset();
}

word Thread::lazy_deopt_from_return_stub_offset() {
  return dart::Thread::lazy_deopt_from_return_stub_offset();
}

word Thread::lazy_deopt_from_throw_stub_offset() {
  return dart::Thread::lazy_deopt_from_throw_stub_offset();
}

word Thread::deoptimize_stub_offset() {
  return dart::Thread::deoptimize_stub_offset();
}

word Thread::enter_safepoint_stub_offset() {
  return dart::Thread::enter_safepoint_stub_offset();
}

word Thread::exit_safepoint_stub_offset() {
  return dart::Thread::exit_safepoint_stub_offset();
}

word Thread::execution_state_offset() {
  return dart::Thread::execution_state_offset();
}

uword Thread::native_execution_state() {
  return dart::Thread::ExecutionState::kThreadInNative;
}

uword Thread::generated_execution_state() {
  return dart::Thread::ExecutionState::kThreadInGenerated;
}

uword Thread::vm_tag_compiled_id() {
  return dart::VMTag::kDartCompiledTagId;
}

#endif  // !defined(TARGET_ARCH_DBC)

#define DECLARE_CONSTANT_OFFSET_GETTER(name)                                   \
  word Thread::name##_address_offset() {                                       \
    return dart::Thread::name##_address_offset();                              \
  }
THREAD_XMM_CONSTANT_LIST(DECLARE_CONSTANT_OFFSET_GETTER)
#undef DECLARE_CONSTANT_OFFSET_GETTER

word Thread::OffsetFromThread(const dart::Object& object) {
  return dart::Thread::OffsetFromThread(object);
}

const word StoreBufferBlock::kSize = dart::StoreBufferBlock::kSize;

const word MarkingStackBlock::kSize = dart::MarkingStackBlock::kSize;

#if !defined(PRODUCT)
word Isolate::single_step_offset() {
  return dart::Isolate::single_step_offset();
}
#endif  // !defined(PRODUCT)

#if !defined(PRODUCT)
word ClassTable::ClassOffsetFor(intptr_t cid) {
  return dart::ClassTable::ClassOffsetFor(cid);
}

word ClassTable::StateOffsetFor(intptr_t cid) {
  return dart::ClassTable::StateOffsetFor(cid);
}

word ClassTable::TableOffsetFor(intptr_t cid) {
  return dart::ClassTable::TableOffsetFor(cid);
}

word ClassTable::CounterOffsetFor(intptr_t cid, bool is_new) {
  return dart::ClassTable::CounterOffsetFor(cid, is_new);
}

word ClassTable::SizeOffsetFor(intptr_t cid, bool is_new) {
  return dart::ClassTable::SizeOffsetFor(cid, is_new);
}
#endif  // !defined(PRODUCT)

const word ClassTable::kSizeOfClassPairLog2 =
    dart::ClassTable::kSizeOfClassPairLog2;

const intptr_t Instructions::kPolymorphicEntryOffset =
    dart::Instructions::kPolymorphicEntryOffset;

const intptr_t Instructions::kMonomorphicEntryOffset =
    dart::Instructions::kMonomorphicEntryOffset;

intptr_t Instructions::HeaderSize() {
  return dart::Instructions::HeaderSize();
}

intptr_t Code::entry_point_offset(CodeEntryKind kind) {
  return dart::Code::entry_point_offset(kind);
}

const word SubtypeTestCache::kTestEntryLength =
    dart::SubtypeTestCache::kTestEntryLength;
const word SubtypeTestCache::kInstanceClassIdOrFunction =
    dart::SubtypeTestCache::kInstanceClassIdOrFunction;
const word SubtypeTestCache::kInstanceTypeArguments =
    dart::SubtypeTestCache::kInstanceTypeArguments;
const word SubtypeTestCache::kInstantiatorTypeArguments =
    dart::SubtypeTestCache::kInstantiatorTypeArguments;
const word SubtypeTestCache::kFunctionTypeArguments =
    dart::SubtypeTestCache::kFunctionTypeArguments;
const word SubtypeTestCache::kInstanceParentFunctionTypeArguments =
    dart::SubtypeTestCache::kInstanceParentFunctionTypeArguments;
const word SubtypeTestCache::kInstanceDelayedFunctionTypeArguments =
    dart::SubtypeTestCache::kInstanceDelayedFunctionTypeArguments;
const word SubtypeTestCache::kTestResult = dart::SubtypeTestCache::kTestResult;

word Context::header_size() {
  return sizeof(dart::RawContext);
}

#if !defined(PRODUCT)
word ClassHeapStats::TraceAllocationMask() {
  return dart::ClassHeapStats::TraceAllocationMask();
}

word ClassHeapStats::state_offset() {
  return dart::ClassHeapStats::state_offset();
}

word ClassHeapStats::allocated_since_gc_new_space_offset() {
  return dart::ClassHeapStats::allocated_since_gc_new_space_offset();
}

word ClassHeapStats::allocated_size_since_gc_new_space_offset() {
  return dart::ClassHeapStats::allocated_size_since_gc_new_space_offset();
}
#endif  // !defined(PRODUCT)

const word Smi::kBits = dart::Smi::kBits;
bool IsSmi(const dart::Object& a) {
  return a.IsSmi();
}

word ToRawSmi(const dart::Object& a) {
  ASSERT(a.IsSmi());
  return reinterpret_cast<word>(a.raw());
}

word ToRawSmi(intptr_t value) {
  return dart::Smi::RawValue(value);
}

bool CanLoadFromThread(const dart::Object& object,
                       word* offset /* = nullptr */) {
  if (dart::Thread::CanLoadFromThread(object)) {
    if (offset != nullptr) {
      *offset = dart::Thread::OffsetFromThread(object);
    }
    return true;
  }
  return false;
}

#if defined(TARGET_ARCH_IA32)
uword Code::EntryPointOf(const dart::Code& code) {
  static_assert(kHostWordSize == kWordSize,
                "Can't embed raw pointers to runtime objects when host and "
                "target word sizes are different");
  return code.EntryPoint();
}

bool CanEmbedAsRawPointerInGeneratedCode(const dart::Object& obj) {
  return obj.IsSmi() || obj.InVMIsolateHeap();
}

word ToRawPointer(const dart::Object& a) {
  static_assert(kHostWordSize == kWordSize,
                "Can't embed raw pointers to runtime objects when host and "
                "target word sizes are different");
  return reinterpret_cast<word>(a.raw());
}
#endif  // defined(TARGET_ARCH_IA32)

const word NativeEntry::kNumCallWrapperArguments =
    dart::NativeEntry::kNumCallWrapperArguments;

word NativeArguments::StructSize() {
  return sizeof(dart::NativeArguments);
}

word RegExp::function_offset(classid_t cid, bool sticky) {
  return dart::RegExp::function_offset(cid, sticky);
}

const word Symbols::kNumberOfOneCharCodeSymbols =
    dart::Symbols::kNumberOfOneCharCodeSymbols;
const word Symbols::kNullCharCodeSymbolOffset =
    dart::Symbols::kNullCharCodeSymbolOffset;

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

#endif  // !defined(DART_PRECOMPILED_RUNTIME)
