// Copyright (c) 2012, 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 VM_OBJECT_STORE_H_
#define VM_OBJECT_STORE_H_

#include "vm/object.h"

namespace dart {

// Forward declarations.
class Isolate;
class ObjectPointerVisitor;

// The object store is a per isolate instance which stores references to
// objects used by the VM.
// TODO(iposva): Move the actual store into the object heap for quick handling
// by snapshots eventually.
class ObjectStore {
 public:
  enum {
    kNone = 0,
    kAsync,
    kCore,
    kCollection,
    kCollectionDev,
    kConvert,
    kIsolate,
    kJson,
    kMath,
    kMirrors,
    kTypedData,
    kUtf,
  };

  ~ObjectStore();

  RawClass* object_class() const {
    ASSERT(object_class_ != Object::null());
    return object_class_;
  }
  void set_object_class(const Class& value) { object_class_ = value.raw(); }
  static intptr_t object_class_offset() {
    return OFFSET_OF(ObjectStore, object_class_);
  }

  RawType* object_type() const { return object_type_; }
  void set_object_type(const Type& value) {
    object_type_ = value.raw();
  }

  RawType* null_type() const { return null_type_; }
  void set_null_type(const Type& value) {
    null_type_ = value.raw();
  }

  RawType* dynamic_type() const { return dynamic_type_; }
  void set_dynamic_type(const Type& value) {
    dynamic_type_ = value.raw();
  }

  RawType* void_type() const { return void_type_; }
  void set_void_type(const Type& value) {
    void_type_ = value.raw();
  }

  RawType* function_type() const { return function_type_; }
  void set_function_type(const Type& value) {
    function_type_ = value.raw();
  }

  RawClass* type_class() const { return type_class_; }
  void set_type_class(const Class& value) { type_class_ = value.raw(); }

  RawClass* type_parameter_class() const { return type_parameter_class_; }
  void set_type_parameter_class(const Class& value) {
    type_parameter_class_ = value.raw();
  }

  RawClass* bounded_type_class() const { return bounded_type_class_; }
  void set_bounded_type_class(const Class& value) {
    bounded_type_class_ = value.raw();
  }

  RawClass* mixin_app_type_class() const { return mixin_app_type_class_; }
  void set_mixin_app_type_class(const Class& value) {
    mixin_app_type_class_ = value.raw();
  }

  RawType* number_type() const { return number_type_; }
  void set_number_type(const Type& value) {
    number_type_ = value.raw();
  }

  RawType* int_type() const { return int_type_; }
  void set_int_type(const Type& value) {
    int_type_ = value.raw();
  }

  RawClass* integer_implementation_class() const {
    return integer_implementation_class_;
  }
  void set_integer_implementation_class(const Class& value) {
    integer_implementation_class_ = value.raw();
  }

  RawClass* smi_class() const { return smi_class_; }
  void set_smi_class(const Class& value) { smi_class_ = value.raw(); }

  RawType* smi_type() const { return smi_type_; }
  void set_smi_type(const Type& value) { smi_type_ = value.raw();
  }

  RawClass* double_class() const { return double_class_; }
  void set_double_class(const Class& value) { double_class_ = value.raw(); }

  RawType* double_type() const { return double_type_; }
  void set_double_type(const Type& value) { double_type_ = value.raw(); }

  RawClass* mint_class() const { return mint_class_; }
  void set_mint_class(const Class& value) { mint_class_ = value.raw(); }

  RawType* mint_type() const { return mint_type_; }
  void set_mint_type(const Type& value) { mint_type_ = value.raw(); }

  RawClass* bigint_class() const { return bigint_class_; }
  void set_bigint_class(const Class& value) { bigint_class_ = value.raw(); }

  RawType* string_type() const { return string_type_; }
  void set_string_type(const Type& value) {
    string_type_ = value.raw();
  }

  RawClass* one_byte_string_class() const { return one_byte_string_class_; }
  void set_one_byte_string_class(const Class& value) {
    one_byte_string_class_ = value.raw();
  }

  RawClass* two_byte_string_class() const { return two_byte_string_class_; }
  void set_two_byte_string_class(const Class& value) {
    two_byte_string_class_ = value.raw();
  }

  RawClass* external_one_byte_string_class() const {
    return external_one_byte_string_class_;
  }
  void set_external_one_byte_string_class(const Class& value) {
    external_one_byte_string_class_ = value.raw();
  }

  RawClass* external_two_byte_string_class() const {
    return external_two_byte_string_class_;
  }
  void set_external_two_byte_string_class(const Class& value) {
    external_two_byte_string_class_ = value.raw();
  }

  RawType* bool_type() const { return bool_type_; }
  void set_bool_type(const Type& value) { bool_type_ = value.raw(); }

  RawClass* bool_class() const { return bool_class_; }
  void set_bool_class(const Class& value) { bool_class_ = value.raw(); }

  RawClass* array_class() const { return array_class_; }
  void set_array_class(const Class& value) { array_class_ = value.raw(); }
  static intptr_t array_class_offset() {
    return OFFSET_OF(ObjectStore, array_class_);
  }

  RawType* array_type() const { return array_type_; }
  void set_array_type(const Type& value) { array_type_ = value.raw(); }

  RawClass* immutable_array_class() const { return immutable_array_class_; }
  void set_immutable_array_class(const Class& value) {
    immutable_array_class_ = value.raw();
  }

  RawClass* growable_object_array_class() const {
    return growable_object_array_class_;
  }
  void set_growable_object_array_class(const Class& value) {
    growable_object_array_class_ = value.raw();
  }
  static intptr_t growable_object_array_class_offset() {
    return OFFSET_OF(ObjectStore, growable_object_array_class_);
  }

  RawClass* float32x4_class() const {
    return float32x4_class_;
  }
  void set_float32x4_class(const Class& value) {
    float32x4_class_ = value.raw();
  }

  RawType* float32x4_type() const { return float32x4_type_; }
  void set_float32x4_type(const Type& value) { float32x4_type_ = value.raw(); }

  RawClass* uint32x4_class() const {
    return uint32x4_class_;
  }
  void set_uint32x4_class(const Class& value) {
    uint32x4_class_ = value.raw();
  }

  RawType* uint32x4_type() const { return uint32x4_type_; }
  void set_uint32x4_type(const Type& value) { uint32x4_type_ = value.raw(); }

  RawArray* typed_data_classes() const {
    return typed_data_classes_;
  }
  void set_typed_data_classes(const Array& value) {
    typed_data_classes_ = value.raw();
  }

  RawClass* error_class() const {
    return error_class_;
  }
  void set_error_class(const Class& value) {
    error_class_ = value.raw();
  }
  static intptr_t error_class_offset() {
    return OFFSET_OF(ObjectStore, error_class_);
  }

  RawClass* stacktrace_class() const {
    return stacktrace_class_;
  }
  void set_stacktrace_class(const Class& value) {
    stacktrace_class_ = value.raw();
  }
  static intptr_t stacktrace_class_offset() {
    return OFFSET_OF(ObjectStore, stacktrace_class_);
  }

  RawClass* jsregexp_class() const {
    return jsregexp_class_;
  }
  void set_jsregexp_class(const Class& value) {
    jsregexp_class_ = value.raw();
  }
  static intptr_t jsregexp_class_offset() {
    return OFFSET_OF(ObjectStore, jsregexp_class_);
  }

  RawClass* weak_property_class() const {
    return weak_property_class_;
  }
  void set_weak_property_class(const Class& value) {
    weak_property_class_ = value.raw();
  }

  RawClass* mirror_reference_class() const {
    return mirror_reference_class_;
  }
  void set_mirror_reference_class(const Class& value) {
    mirror_reference_class_ = value.raw();
  }

  RawArray* symbol_table() const { return symbol_table_; }
  void set_symbol_table(const Array& value) { symbol_table_ = value.raw(); }

  RawArray* canonical_type_arguments() const {
    return canonical_type_arguments_;
  }
  void set_canonical_type_arguments(const Array& value) {
    canonical_type_arguments_ = value.raw();
  }

  RawLibrary* async_library() const { return async_library_; }
  RawLibrary* builtin_library() const { return builtin_library_; }
  RawLibrary* core_library() const { return core_library_; }
  RawLibrary* collection_library() const { return collection_library_; }
  RawLibrary* collection_dev_library() const {
    return collection_dev_library_;
  }
  RawLibrary* convert_library() const { return convert_library_; }
  RawLibrary* isolate_library() const { return isolate_library_; }
  RawLibrary* json_library() const { return json_library_; }
  RawLibrary* math_library() const { return math_library_; }
  RawLibrary* mirrors_library() const { return mirrors_library_; }
  RawLibrary* typed_data_library() const { return typed_data_library_; }
  RawLibrary* utf_library() const { return utf_library_; }
  void set_bootstrap_library(intptr_t index, const Library& value) {
    switch (index) {
      case kAsync:
        async_library_ = value.raw();
        break;
      case kCore:
        core_library_ = value.raw();
        break;
      case kCollection:
        collection_library_ = value.raw();
        break;
      case kCollectionDev:
        collection_dev_library_ = value.raw();
        break;
      case kConvert:
        convert_library_ = value.raw();
        break;
      case kIsolate:
        isolate_library_ = value.raw();
        break;
      case kJson:
        json_library_ = value.raw();
        break;
      case kMath:
        math_library_ = value.raw();
        break;
      case kMirrors:
        mirrors_library_ = value.raw();
        break;
      case kTypedData:
        typed_data_library_ = value.raw();
        break;
      case kUtf:
        utf_library_ = value.raw();
        break;
      default:
        UNREACHABLE();
    }
  }

  void set_builtin_library(const Library& value) {
    builtin_library_ = value.raw();
  }

  RawLibrary* native_wrappers_library() const {
    return native_wrappers_library_;
  }
  void set_native_wrappers_library(const Library& value) {
    native_wrappers_library_ = value.raw();
  }

  RawLibrary* root_library() const { return root_library_; }
  void set_root_library(const Library& value) {
    root_library_ = value.raw();
  }

  RawGrowableObjectArray* libraries() const { return libraries_; }
  void set_libraries(const GrowableObjectArray& value) {
    libraries_ = value.raw();
  }

  RawGrowableObjectArray* pending_classes() const { return pending_classes_; }
  void set_pending_classes(const GrowableObjectArray& value) {
    ASSERT(!value.IsNull());
    pending_classes_ = value.raw();
  }

  RawError* sticky_error() const { return sticky_error_; }
  void set_sticky_error(const Error& value) {
    ASSERT(!value.IsNull());
    sticky_error_ = value.raw();
  }
  void clear_sticky_error() { sticky_error_ = Error::null(); }

  RawString* unhandled_exception_handler() const {
    return unhandled_exception_handler_;
  }
  void set_unhandled_exception_handler(const String& value) {
    unhandled_exception_handler_ = value.raw();
  }

  RawContext* empty_context() const { return empty_context_; }
  void set_empty_context(const Context& value) {
    empty_context_ = value.raw();
  }

  RawInstance* stack_overflow() const { return stack_overflow_; }
  void set_stack_overflow(const Instance& value) {
    stack_overflow_ = value.raw();
  }

  RawInstance* out_of_memory() const { return out_of_memory_; }
  void set_out_of_memory(const Instance& value) {
    out_of_memory_ = value.raw();
  }

  RawStacktrace* preallocated_stack_trace() const {
    return preallocated_stack_trace_;
  }
  void set_preallocated_stack_trace(const Stacktrace& value) {
    preallocated_stack_trace_ = value.raw();
  }

  RawArray* keyword_symbols() const { return keyword_symbols_; }
  void set_keyword_symbols(const Array& value) {
    keyword_symbols_ = value.raw();
  }
  void InitKeywordTable();

  RawFunction* receive_port_create_function() const {
    return receive_port_create_function_;
  }
  void set_receive_port_create_function(const Function& function) {
    receive_port_create_function_ = function.raw();
  }

  RawFunction* lookup_receive_port_function() const {
    return lookup_receive_port_function_;
  }
  void set_lookup_receive_port_function(const Function& function) {
    lookup_receive_port_function_ = function.raw();
  }

  RawFunction* handle_message_function() const {
    return handle_message_function_;
  }
  void set_handle_message_function(const Function& function) {
    handle_message_function_ = function.raw();
  }

  // Visit all object pointers.
  void VisitObjectPointers(ObjectPointerVisitor* visitor);

  // Called to initialize objects required by the vm but which invoke
  // dart code.  If an error occurs then false is returned and error
  // information is stored in sticky_error().
  bool PreallocateObjects();

  static void Init(Isolate* isolate);

 private:
  ObjectStore();

  RawObject** from() { return reinterpret_cast<RawObject**>(&object_class_); }
  RawClass* object_class_;
  RawType* object_type_;
  RawType* null_type_;
  RawType* dynamic_type_;
  RawType* void_type_;
  RawType* function_type_;
  RawClass* type_class_;
  RawClass* type_parameter_class_;
  RawClass* bounded_type_class_;
  RawClass* mixin_app_type_class_;
  RawType* number_type_;
  RawType* int_type_;
  RawClass* integer_implementation_class_;
  RawClass* smi_class_;
  RawType* smi_type_;
  RawClass* mint_class_;
  RawType* mint_type_;
  RawClass* bigint_class_;
  RawClass* double_class_;
  RawType* double_type_;
  RawType* float32x4_type_;
  RawType* uint32x4_type_;
  RawType* string_type_;
  RawClass* one_byte_string_class_;
  RawClass* two_byte_string_class_;
  RawClass* external_one_byte_string_class_;
  RawClass* external_two_byte_string_class_;
  RawType* bool_type_;
  RawClass* bool_class_;
  RawClass* array_class_;
  RawType* array_type_;
  RawClass* immutable_array_class_;
  RawClass* growable_object_array_class_;
  RawClass* float32x4_class_;
  RawClass* uint32x4_class_;
  RawArray* typed_data_classes_;
  RawClass* error_class_;
  RawClass* stacktrace_class_;
  RawClass* jsregexp_class_;
  RawClass* weak_property_class_;
  RawClass* mirror_reference_class_;
  RawArray* symbol_table_;
  RawArray* canonical_type_arguments_;
  RawLibrary* async_library_;
  RawLibrary* builtin_library_;
  RawLibrary* core_library_;
  RawLibrary* collection_library_;
  RawLibrary* collection_dev_library_;
  RawLibrary* convert_library_;
  RawLibrary* isolate_library_;
  RawLibrary* json_library_;
  RawLibrary* math_library_;
  RawLibrary* mirrors_library_;
  RawLibrary* native_wrappers_library_;
  RawLibrary* root_library_;
  RawLibrary* typed_data_library_;
  RawLibrary* utf_library_;
  RawGrowableObjectArray* libraries_;
  RawGrowableObjectArray* pending_classes_;
  RawError* sticky_error_;
  RawString* unhandled_exception_handler_;
  RawContext* empty_context_;
  RawInstance* stack_overflow_;
  RawInstance* out_of_memory_;
  RawStacktrace* preallocated_stack_trace_;
  RawArray* keyword_symbols_;
  RawFunction* receive_port_create_function_;
  RawFunction* lookup_receive_port_function_;
  RawFunction* handle_message_function_;
  RawObject** to() { return reinterpret_cast<RawObject**>(&keyword_symbols_); }

  friend class SnapshotReader;

  DISALLOW_COPY_AND_ASSIGN(ObjectStore);
};

}  // namespace dart

#endif  // VM_OBJECT_STORE_H_
